From: Chris Lattner Date: Wed, 6 Oct 2010 00:45:24 +0000 (+0000) Subject: lets go all meta and define new X86 type wrappers that declare the associated X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=417b54354b3fcccb4f5919b8d2d9dcd8bba50069;p=oota-llvm.git lets go all meta and define new X86 type wrappers that declare the associated gunk that goes along with an MVT (e.g. reg class, preferred load operation, memory operand) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@115727 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/X86/X86InstrArithmetic.td b/lib/Target/X86/X86InstrArithmetic.td index 8e7cb4248b9..33b70592915 100644 --- a/lib/Target/X86/X86InstrArithmetic.td +++ b/lib/Target/X86/X86InstrArithmetic.td @@ -495,24 +495,57 @@ let CodeSize = 2 in { } // CodeSize = 2 } // Defs = [EFLAGS] +/// X86TypeInfo - This is a bunch of information that describes relevant X86 +/// information about value types. For example, it can tell you what the +/// register class and preferred load to use. +class X86TypeInfo { + /// VT - This is the value type itself. + ValueType VT = vt; + + /// InstrSuffix - This is the suffix used on instructions with this type. For + /// example, i8 -> "b", i16 -> "w", i32 -> "l", i64 -> "q". + string InstrSuffix = instrsuffix; + + /// RegClass - This is the register class associated with this type. For + /// example, i8 -> GR8, i16 -> GR16, i32 -> GR32, i64 -> GR64. + RegisterClass RegClass = regclass; + + /// LoadNode - This is the load node associated with this type. For + /// example, i8 -> loadi8, i16 -> loadi16, i32 -> loadi32, i64 -> loadi64. + PatFrag LoadNode = loadnode; + + /// MemOperand - This is the memory operand associated with this type. For + /// example, i8 -> i8mem, i16 -> i16mem, i32 -> i32mem, i64 -> i64mem. + X86MemOperand MemOperand = memoperand; +} + +def Xi8 : X86TypeInfo; +def Xi16 : X86TypeInfo; +def Xi32 : X86TypeInfo; +def Xi64 : X86TypeInfo; + -class BinOpRR opcode, Format format, string mnemonic, - X86RegisterClass regclass, SDNode opnode> - : I opcode, string mnemonic, X86TypeInfo typeinfo, + SDNode opnode, Format format> + : I; + [(set typeinfo.RegClass:$dst, EFLAGS, + (opnode typeinfo.RegClass:$src1, typeinfo.RegClass:$src2))]>; -class BinOpRM opcode, string mnemonic, - X86RegisterClass regclass, SDNode opnode, PatFrag loadnode, - X86MemOperand operand> +class BinOpRM opcode, string mnemonic, X86TypeInfo typeinfo, + SDNode opnode, PatFrag loadnode> : I; + [(set typeinfo.RegClass:$dst, EFLAGS, + (opnode typeinfo.RegClass:$src1, (loadnode addr:$src2)))]>; // Logical operators. @@ -520,10 +553,10 @@ let Defs = [EFLAGS] in { let Constraints = "$src1 = $dst" in { let isCommutable = 1 in { // X = AND Y, Z --> X = AND Z, Y -def AND8rr : BinOpRR<0x20, MRMDestReg, "and", GR8 , X86and_flag>; -def AND16rr : BinOpRR<0x21, MRMDestReg, "and", GR16, X86and_flag>, OpSize; -def AND32rr : BinOpRR<0x21, MRMDestReg, "and", GR32, X86and_flag>; -def AND64rr : BinOpRR<0x21, MRMDestReg, "and", GR64, X86and_flag>, REX_W; +def AND8rr : BinOpRR<0x20, "and", Xi8 , X86and_flag, MRMDestReg>; +def AND16rr : BinOpRR<0x21, "and", Xi16, X86and_flag, MRMDestReg>, OpSize; +def AND32rr : BinOpRR<0x21, "and", Xi32, X86and_flag, MRMDestReg>; +def AND64rr : BinOpRR<0x21, "and", Xi64, X86and_flag, MRMDestReg>, REX_W; } // isCommutable @@ -543,10 +576,10 @@ def AND64rr_REV : RI<0x23, MRMSrcReg, (outs GR64:$dst), "and{q}\t{$src2, $dst|$dst, $src2}", []>; } -def AND8rm : BinOpRM<0x22, "and", GR8 , X86and_flag, loadi8 , i8mem>; -def AND16rm : BinOpRM<0x23, "and", GR16, X86and_flag, loadi16, i16mem>, OpSize; -def AND32rm : BinOpRM<0x23, "and", GR32, X86and_flag, loadi32, i32mem>; -def AND64rm : BinOpRM<0x23, "and", GR64, X86and_flag, loadi64, i64mem>, REX_W; +def AND8rm : BinOpRM<0x22, "and", Xi8 , X86and_flag, loadi8 >; +def AND16rm : BinOpRM<0x23, "and", Xi16, X86and_flag, loadi16>, OpSize; +def AND32rm : BinOpRM<0x23, "and", Xi32, X86and_flag, loadi32>; +def AND64rm : BinOpRM<0x23, "and", Xi64, X86and_flag, loadi64>, REX_W; def AND8ri : Ii8<0x80, MRM4r, (outs GR8 :$dst), (ins GR8 :$src1, i8imm :$src2), diff --git a/lib/Target/X86/X86RegisterInfo.td b/lib/Target/X86/X86RegisterInfo.td index e0dc5cdaed5..959c01ebaea 100644 --- a/lib/Target/X86/X86RegisterInfo.td +++ b/lib/Target/X86/X86RegisterInfo.td @@ -261,16 +261,6 @@ let Namespace = "X86" in { // implicitly defined to be the register allocation order. // -class X86RegisterClass regTypes, - int alignment, string instrsuffix, - list regList> - : RegisterClass { - // This is the suffix used on instructions with this class of register. For - // example, GR8 -> "b", GR16 -> "w", GR32 -> "l", GR64 -> "q". - string InstrSuffix = instrsuffix; -} - - // List call-clobbered registers before callee-save registers. RBX, RBP, (and // R12, R13, R14, and R15 for X86-64) are callee-save registers. // In 64-mode, there are 12 additional i8 registers, SIL, DIL, BPL, SPL, and @@ -282,9 +272,9 @@ class X86RegisterClass regTypes, // instruction requiring a REX prefix, while SIL, DIL, BPL, R8D, etc. // require a REX prefix. For example, "addb %ah, %dil" and "movzbl %ah, %r8d" // cannot be encoded. -def GR8 : X86RegisterClass<"X86", [i8], 8, "b", - [AL, CL, DL, AH, CH, DH, BL, BH, SIL, DIL, BPL, SPL, - R8B, R9B, R10B, R11B, R14B, R15B, R12B, R13B]> { +def GR8 : RegisterClass<"X86", [i8], 8, + [AL, CL, DL, AH, CH, DH, BL, BH, SIL, DIL, BPL, SPL, + R8B, R9B, R10B, R11B, R14B, R15B, R12B, R13B]> { let MethodProtos = [{ iterator allocation_order_begin(const MachineFunction &MF) const; iterator allocation_order_end(const MachineFunction &MF) const; @@ -326,9 +316,9 @@ def GR8 : X86RegisterClass<"X86", [i8], 8, "b", }]; } -def GR16 : X86RegisterClass<"X86", [i16], 16, "w", - [AX, CX, DX, SI, DI, BX, BP, SP, - R8W, R9W, R10W, R11W, R14W, R15W, R12W, R13W]> { +def GR16 : RegisterClass<"X86", [i16], 16, + [AX, CX, DX, SI, DI, BX, BP, SP, + R8W, R9W, R10W, R11W, R14W, R15W, R12W, R13W]> { let SubRegClasses = [(GR8 sub_8bit, sub_8bit_hi)]; let MethodProtos = [{ iterator allocation_order_begin(const MachineFunction &MF) const; @@ -378,9 +368,9 @@ def GR16 : X86RegisterClass<"X86", [i16], 16, "w", }]; } -def GR32 : X86RegisterClass<"X86", [i32], 32, "l", - [EAX, ECX, EDX, ESI, EDI, EBX, EBP, ESP, - R8D, R9D, R10D, R11D, R14D, R15D, R12D, R13D]> { +def GR32 : RegisterClass<"X86", [i32], 32, + [EAX, ECX, EDX, ESI, EDI, EBX, EBP, ESP, + R8D, R9D, R10D, R11D, R14D, R15D, R12D, R13D]> { let SubRegClasses = [(GR8 sub_8bit, sub_8bit_hi), (GR16 sub_16bit)]; let MethodProtos = [{ iterator allocation_order_begin(const MachineFunction &MF) const; @@ -433,9 +423,9 @@ def GR32 : X86RegisterClass<"X86", [i32], 32, "l", // GR64 - 64-bit GPRs. This oddly includes RIP, which isn't accurate, since // RIP isn't really a register and it can't be used anywhere except in an // address, but it doesn't cause trouble. -def GR64 : X86RegisterClass<"X86", [i64], 64, "q", - [RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11, - RBX, R14, R15, R12, R13, RBP, RSP, RIP]> { +def GR64 : RegisterClass<"X86", [i64], 64, + [RAX, RCX, RDX, RSI, RDI, R8, R9, R10, R11, + RBX, R14, R15, R12, R13, RBP, RSP, RIP]> { let SubRegClasses = [(GR8 sub_8bit, sub_8bit_hi), (GR16 sub_16bit), (GR32 sub_32bit)];