diff options
author | Chris Lattner <sabre@nondot.org> | 2004-03-31 22:02:13 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2004-03-31 22:02:13 +0000 |
commit | 1c54a8544788156d6864430182a3a79b8839b7da (patch) | |
tree | 8558ca05d1d9b8819a4e2bae5a45a29459738694 | |
parent | 0e28eca4bc956c72899b470607c0e8fc3c4a35a8 (diff) |
Add FP conditional move instructions, which annoyingly have special properties
that require the asmwriter to be extended (printing implicit uses before the
explicit operands)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@12574 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/X86/X86.td | 6 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrInfo.h | 16 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrInfo.td | 21 |
3 files changed, 33 insertions, 10 deletions
diff --git a/lib/Target/X86/X86.td b/lib/Target/X86/X86.td index f92bfa10fc..5584dd0d19 100644 --- a/lib/Target/X86/X86.td +++ b/lib/Target/X86/X86.td @@ -34,9 +34,11 @@ def X86InstrInfo : InstrInfo { // Define how we want to layout our TargetSpecific information field... This // should be kept up-to-date with the fields in the X86InstrInfo.h file. let TSFlagsFields = ["FormBits" , "hasOpSizePrefix" , "Prefix", "MemTypeBits", - "ImmTypeBits", "FPFormBits", "printImplicitUses", "Opcode"]; + "ImmTypeBits", "FPFormBits", "printImplicitUsesAfter", + "printImplicitUsesBefore", "Opcode"]; let TSFlagsShifts = [0, 5, 6, 10, 13, - 15, 18, 19]; + 15, 18, 19, + 20]; } def X86 : Target { diff --git a/lib/Target/X86/X86InstrInfo.h b/lib/Target/X86/X86InstrInfo.h index 54e3686973..61cc5e18ed 100644 --- a/lib/Target/X86/X86InstrInfo.h +++ b/lib/Target/X86/X86InstrInfo.h @@ -155,13 +155,21 @@ namespace X86II { // argument. For example: fadd, fsub, fmul, etc... TwoArgFP = 4 << FPTypeShift, + // CondMovFP - "2 operand" floating point conditional move instructions. + CondMovFP = 5 << FPTypeShift, + // SpecialFP - Special instruction forms. Dispatch by opcode explicitly. - SpecialFP = 5 << FPTypeShift, + SpecialFP = 6 << FPTypeShift, + + // PrintImplUsesAfter - Print out implicit uses in the assembly output after + // the normal operands. + PrintImplUsesAfter = 1 << 18, - // PrintImplUses - Print out implicit uses in the assembly output. - PrintImplUses = 1 << 18, + // PrintImplUsesBefore - Print out implicit uses in the assembly output before + // the normal operands. + PrintImplUsesBefore = 1 << 19, - OpcodeShift = 19, + OpcodeShift = 20, OpcodeMask = 0xFF << OpcodeShift, // Bits 25 -> 31 are unused }; diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index 007b693591..d32dd3e12b 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -66,7 +66,8 @@ def ZeroArgFP : FPFormat<1>; def OneArgFP : FPFormat<2>; def OneArgFPRW : FPFormat<3>; def TwoArgFP : FPFormat<4>; -def SpecialFP : FPFormat<5>; +def CondMovFP : FPFormat<5>; +def SpecialFP : FPFormat<6>; class X86Inst<string nam, bits<8> opcod, Format f, MemType m, ImmType i> : Instruction { @@ -83,7 +84,8 @@ class X86Inst<string nam, bits<8> opcod, Format f, MemType m, ImmType i> : Instr // Attributes specific to X86 instructions... bit hasOpSizePrefix = 0; // Does this inst have a 0x66 prefix? - bit printImplicitUses = 0; // Should we print implicit uses of this inst? + bit printImplicitUsesBefore = 0; // Should we print implicit uses before this inst? + bit printImplicitUsesAfter = 0; // Should we print implicit uses after this inst? bits<4> Prefix = 0; // Which prefix byte does this inst have? FPFormat FPForm; // What flavor of FP instruction is this? @@ -138,7 +140,7 @@ class Im16i8<string n, bits<8> o, Format f> : X86Inst<n, o, f, Mem16, Imm8>; class Im32i8<string n, bits<8> o, Format f> : X86Inst<n, o, f, Mem32, Imm8>; // Helper for shift instructions -class UsesCL { list<Register> Uses = [CL]; bit printImplicitUses = 1; } +class UsesCL { list<Register> Uses = [CL]; bit printImplicitUsesAfter = 1; } //===----------------------------------------------------------------------===// // Instruction list... @@ -694,6 +696,17 @@ def FpUCOM : FPI<"FUCOM", 0, Pseudo, TwoArgFP>; // FPSW = fucom f1, f2 def FpGETRESULT : FPI<"FGETRESULT",0, Pseudo, SpecialFP>; // FPR = ST(0) def FpSETRESULT : FPI<"FSETRESULT",0, Pseudo, SpecialFP>; // ST(0) = FPR + +// Floating point cmovs... +let isTwoAddress = 1, Uses = [ST0], Defs = [ST0], printImplicitUsesBefore = 1 in { + def FCMOVB : FPI <"fcmovb" , 0xC0, AddRegFrm, CondMovFP>, DA; // fcmovb ST(i) -> ST(0) + def FCMOVBE : FPI <"fcmovbe", 0xD0, AddRegFrm, CondMovFP>, DA; // fcmovbe ST(i) -> ST(0) + def FCMOVE : FPI <"fcmove" , 0xC8, AddRegFrm, CondMovFP>, DA; // fcmove ST(i) -> ST(0) + def FCMOVAE : FPI <"fcmovae", 0xC0, AddRegFrm, CondMovFP>, DB; // fcmovae ST(i) -> ST(0) + def FCMOVA : FPI <"fcmova" , 0xD0, AddRegFrm, CondMovFP>, DB; // fcmova ST(i) -> ST(0) + def FCMOVNE : FPI <"fcmovne", 0xC8, AddRegFrm, CondMovFP>, DB; // fcmovne ST(i) -> ST(0) +} + // Floating point loads & stores... def FLDrr : FPI <"fld" , 0xC0, AddRegFrm, NotFP>, D9; // push(ST(i)) def FLD32m : FPI32m <"fld" , 0xD9, MRM0m , ZeroArgFP>; // load float @@ -735,7 +748,7 @@ class FPST0rInst<string n, bits<8> o> : I<n, o, AddRegFrm>, D8 { list<Register> Defs = [ST0]; } class FPrST0Inst<string n, bits<8> o> : I<n, o, AddRegFrm>, DC { - bit printImplicitUses = 1; + bit printImplicitUsesAfter = 1; list<Register> Uses = [ST0]; } class FPrST0PInst<string n, bits<8> o> : I<n, o, AddRegFrm>, DE { |