/* * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.sun.max.asm.gen.cisc.ia32; import static com.sun.max.asm.gen.cisc.x86.AddressingMethodCode.*; import static com.sun.max.asm.gen.cisc.x86.FloatingPointOperandCode.*; import static com.sun.max.asm.gen.cisc.x86.ModRMGroup.Opcode.*; import static com.sun.max.asm.gen.cisc.x86.OperandCode.*; import static com.sun.max.asm.gen.cisc.x86.OperandTypeCode.*; import static com.sun.max.asm.gen.cisc.x86.RegisterOperandCode.*; import static com.sun.max.asm.ia32.IA32GeneralRegister16.*; import static com.sun.max.asm.ia32.IA32GeneralRegister32.*; import static com.sun.max.asm.ia32.IA32GeneralRegister8.*; import java.util.*; import com.sun.max.asm.gen.*; import com.sun.max.asm.gen.cisc.x86.*; /** * See A-7 in the book. * * @see com.sun.max.asm.x86 */ public enum IA32ModRMGroup implements ModRMGroup { GROUP_1( modRM(OPCODE_0, "ADD"), modRM(OPCODE_1, "OR"), modRM(OPCODE_2, "ADC"), modRM(OPCODE_3, "SBB"), modRM(OPCODE_4, "AND"), modRM(OPCODE_5, "SUB"), modRM(OPCODE_6, "XOR"), modRM(OPCODE_7, "CMP") ), GROUP_2( modRM(OPCODE_0, "ROL"), modRM(OPCODE_1, "ROR"), modRM(OPCODE_2, "RCL"), modRM(OPCODE_3, "RCR"), modRM(OPCODE_4, "SHL"), modRM(OPCODE_5, "SHR"), modRM(OPCODE_7, "SAR") ), GROUP_3b( modRM(OPCODE_0, "TEST", Eb.excludeExternalTestArguments(AL), Ib), modRM(OPCODE_1, "TEST", Eb.excludeExternalTestArguments(AL), Ib), modRM(OPCODE_2, "NOT", Eb), modRM(OPCODE_3, "NEG", Eb), modRM(OPCODE_4, "MUL", Eb, new ExternalOmission(AL)), modRM(OPCODE_5, "IMUL", Eb, new ExternalOmission(AL)), modRM(OPCODE_6, "DIV", Eb, new ExternalOmission(AL)), modRM(OPCODE_7, "IDIV", Eb, new ExternalOmission(AL)) ), GROUP_3v( modRM(OPCODE_0, "TEST", Ev.excludeExternalTestArguments(AX, EAX), Iv), modRM(OPCODE_1, "TEST", Ev.excludeExternalTestArguments(AX, EAX), Iv), modRM(OPCODE_2, "NOT", Ev), modRM(OPCODE_3, "NEG", Ev), modRM(OPCODE_4, "MUL", Ev, eAX.omitExternally()), modRM(OPCODE_5, "IMUL", Ev, eAX.omitExternally()), modRM(OPCODE_6, "DIV", Ev, eAX.omitExternally()), modRM(OPCODE_7, "IDIV", Ev, eAX.omitExternally()) ), GROUP_4( modRM(OPCODE_0, "INC"), modRM(OPCODE_1, "DEC") ), GROUP_5( modRM(OPCODE_0, "INC", v, Ev.excludeExternalTestArguments(AX, CX, DX, BX, SP, BP, SI, DI, EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI)), modRM(OPCODE_1, "DEC", v, Ev.excludeExternalTestArguments(AX, CX, DX, BX, SP, BP, SI, DI, EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI)), modRM(OPCODE_2, "CALL", Ev), modRM(OPCODE_3, "CALL", Mp), modRM(OPCODE_4, "JMP", Ev), modRM(OPCODE_5, "JMP", Mp), modRM(OPCODE_6, "PUSH", Ev) ), GROUP_6a( modRM(OPCODE_0, "SLDT", Mw), modRM(OPCODE_1, "STR", Mw), modRM(OPCODE_2, "LLDT", Ew), modRM(OPCODE_3, "LTR", Ew), modRM(OPCODE_4, "VERR", Ew), modRM(OPCODE_5, "VERW", Ew) ), GROUP_6b( modRM(OPCODE_0, "SLDT", Rv), modRM(OPCODE_1, "STR", Rv) ), GROUP_7a( modRM(OPCODE_0, "SGDT", Ms), modRM(OPCODE_1, "SIDT", Ms), modRM(OPCODE_2, "LGDT", Ms), modRM(OPCODE_3, "LIDT", Ms), modRM(OPCODE_4, "SMSW", Mw), modRM(OPCODE_6, "LMSW", Ew), modRM(OPCODE_7, "INVLPG", M) ), GROUP_7b( modRM(OPCODE_4, "SMSW", Rv) ), GROUP_8( modRM(OPCODE_4, "BT"), modRM(OPCODE_5, "BTS"), modRM(OPCODE_6, "BTR"), modRM(OPCODE_7, "BTC") ), GROUP_9( modRM(OPCODE_1, "CMPXCHG8B", Mq) ), GROUP_10( modRM(OPCODE_0, "UD2"), modRM(OPCODE_1, "UD2"), modRM(OPCODE_2, "UD2"), modRM(OPCODE_3, "UD2"), modRM(OPCODE_4, "UD2"), modRM(OPCODE_5, "UD2"), modRM(OPCODE_6, "UD2"), modRM(OPCODE_7, "UD2") ), GROUP_11( modRM(OPCODE_2, "PSRLW", PRq, Ib), modRM(OPCODE_4, "PSRAW", PRq, Ib), modRM(OPCODE_6, "PSLLW", PRq, Ib) ), GROUP_12( modRM(OPCODE_2, "PSRLD", PRq, Ib), modRM(OPCODE_4, "PSRAD", PRq, Ib), modRM(OPCODE_6, "PSLLD", PRq, Ib) ), GROUP_13a( modRM(OPCODE_2, "PSRLQ", PRq, Ib), modRM(OPCODE_6, "PSLLQ", PRq, Ib) ), GROUP_13b( modRM(OPCODE_2, "PSRLQ", VRq, Ib), modRM(OPCODE_3, "PSRLDQ", VRdq, Ib), modRM(OPCODE_6, "PSLLQ", VRq, Ib), modRM(OPCODE_7, "PSLLDQ", VRdq, Ib) ), GROUP_15b( modRM(OPCODE_5, "LFENCE"), modRM(OPCODE_6, "MFENCE"), modRM(OPCODE_7, "SFENCE") ), FP_D8( modRM(OPCODE_0, "FADD", single_real), modRM(OPCODE_1, "FMUL", single_real), modRM(OPCODE_2, "FCOM", single_real), modRM(OPCODE_3, "FCOMP", single_real), modRM(OPCODE_4, "FSUB", single_real), modRM(OPCODE_5, "FSUBR", single_real), modRM(OPCODE_6, "FDIV", single_real), modRM(OPCODE_7, "FDIVR", single_real) ), FP_D9( modRM(OPCODE_0, "FLD", single_real), modRM(OPCODE_2, "FST", single_real), modRM(OPCODE_3, "FSTP", single_real), modRM(OPCODE_4, "FLDENV", bytes_14_28), modRM(OPCODE_5, "FLDCW", bytes_2), modRM(OPCODE_6, "FSTENV", bytes_14_28), modRM(OPCODE_7, "FSTCW", bytes_2) ), FP_DA( modRM(OPCODE_0, "FIADD", short_integer), modRM(OPCODE_1, "FIMUL", short_integer), modRM(OPCODE_2, "FICOM", short_integer), modRM(OPCODE_3, "FICOMP", short_integer), modRM(OPCODE_4, "FISUB", short_integer), modRM(OPCODE_5, "FISUBR", short_integer), modRM(OPCODE_6, "FIDIV", short_integer), modRM(OPCODE_7, "FIDIVR", short_integer) ), FP_DB( modRM(OPCODE_0, "FILD", short_integer), modRM(OPCODE_2, "FIST", short_integer), modRM(OPCODE_3, "FISTP", short_integer), modRM(OPCODE_5, "FLD", extended_real), modRM(OPCODE_7, "FSTP", extended_real) ), FP_DC( modRM(OPCODE_0, "FADD", double_real), modRM(OPCODE_1, "FMUL", double_real), modRM(OPCODE_2, "FCOM", double_real), modRM(OPCODE_3, "FCOMP", double_real), modRM(OPCODE_4, "FSUB", double_real), modRM(OPCODE_5, "FSUBR", double_real), modRM(OPCODE_6, "FDIV", double_real), modRM(OPCODE_7, "FDIVR", double_real) ), FP_DD( modRM(OPCODE_0, "FLD", double_real), modRM(OPCODE_2, "FST", double_real), modRM(OPCODE_3, "FSTP", double_real), modRM(OPCODE_4, "FRSTOR", bytes_98_108), modRM(OPCODE_6, "FSAVE", bytes_98_108), modRM(OPCODE_7, "FSTSW", bytes_2) ), FP_DE( modRM(OPCODE_0, "FIADD", word_integer), modRM(OPCODE_1, "FIMUL", word_integer), modRM(OPCODE_2, "FICOM", word_integer), modRM(OPCODE_3, "FICOMP", word_integer), modRM(OPCODE_4, "FISUB", word_integer), modRM(OPCODE_5, "FISUBR", word_integer), modRM(OPCODE_6, "FIDIV", word_integer), modRM(OPCODE_7, "FIDIVR", word_integer) ), FP_DF( modRM(OPCODE_0, "FILD", word_integer), modRM(OPCODE_2, "FIST", word_integer), modRM(OPCODE_3, "FISTP", word_integer), modRM(OPCODE_4, "FBLD", packed_bcd), modRM(OPCODE_5, "FILD", long_integer), modRM(OPCODE_6, "FBSTP", packed_bcd), modRM(OPCODE_7, "FISTP", long_integer) ); private static ModRMDescription modRM(ModRMGroup.Opcode opcode, String name, Object... specifications) { return new ModRMDescription(opcode, name, Arrays.asList(specifications)); } private final ModRMDescription[] instructionDescriptions; private IA32ModRMGroup(ModRMDescription... instructionDescriptions) { this.instructionDescriptions = instructionDescriptions; } public ModRMDescription getInstructionDescription(ModRMGroup.Opcode opcode) { for (ModRMDescription instructionDescription : instructionDescriptions) { if (instructionDescription.opcode() == opcode) { return instructionDescription; } } return null; } }