diff options
Diffstat (limited to 'lib/Target/X86')
-rw-r--r-- | lib/Target/X86/MCTargetDesc/X86BaseInfo.h | 27 | ||||
-rw-r--r-- | lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp | 17 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrArithmetic.td | 18 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrFormats.td | 62 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrInfo.td | 15 |
5 files changed, 84 insertions, 55 deletions
diff --git a/lib/Target/X86/MCTargetDesc/X86BaseInfo.h b/lib/Target/X86/MCTargetDesc/X86BaseInfo.h index 49d8b11658..c085f14781 100644 --- a/lib/Target/X86/MCTargetDesc/X86BaseInfo.h +++ b/lib/Target/X86/MCTargetDesc/X86BaseInfo.h @@ -395,20 +395,21 @@ namespace X86II { // This three-bit field describes the size of an immediate operand. Zero is // unused so that we can tell if we forgot to set a value. ImmShift = REXShift + 1, - ImmMask = 7 << ImmShift, + ImmMask = 15 << ImmShift, Imm8 = 1 << ImmShift, Imm8PCRel = 2 << ImmShift, Imm16 = 3 << ImmShift, Imm16PCRel = 4 << ImmShift, Imm32 = 5 << ImmShift, Imm32PCRel = 6 << ImmShift, - Imm64 = 7 << ImmShift, + Imm32S = 7 << ImmShift, + Imm64 = 8 << ImmShift, //===------------------------------------------------------------------===// // FP Instruction Classification... Zero is non-fp instruction. // FPTypeMask - Mask for all of the FP types... - FPTypeShift = ImmShift + 3, + FPTypeShift = ImmShift + 4, FPTypeMask = 7 << FPTypeShift, // NotFP - The default, set for instructions that do not use FP registers. @@ -557,6 +558,7 @@ namespace X86II { case X86II::Imm16: case X86II::Imm16PCRel: return 2; case X86II::Imm32: + case X86II::Imm32S: case X86II::Imm32PCRel: return 4; case X86II::Imm64: return 8; } @@ -574,6 +576,25 @@ namespace X86II { case X86II::Imm8: case X86II::Imm16: case X86II::Imm32: + case X86II::Imm32S: + case X86II::Imm64: + return false; + } + } + + /// isImmSigned - Return true if the immediate of the specified instruction's + /// TSFlags indicates that it is signed. + inline unsigned isImmSigned(uint64_t TSFlags) { + switch (TSFlags & X86II::ImmMask) { + default: llvm_unreachable("Unknown immediate signedness"); + case X86II::Imm32S: + return true; + case X86II::Imm8: + case X86II::Imm8PCRel: + case X86II::Imm16: + case X86II::Imm16PCRel: + case X86II::Imm32: + case X86II::Imm32PCRel: case X86II::Imm64: return false; } diff --git a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp index 1c6a0b2da6..52d6d14a8f 100644 --- a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp +++ b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp @@ -233,6 +233,12 @@ static MCFixupKind getImmFixupKind(uint64_t TSFlags) { unsigned Size = X86II::getSizeOfImm(TSFlags); bool isPCRel = X86II::isImmPCRel(TSFlags); + if (X86II::isImmSigned(TSFlags)) { + switch (Size) { + default: llvm_unreachable("Unsupported signed fixup size!"); + case 4: return MCFixupKind(X86::reloc_signed_4byte); + } + } return MCFixup::getKindForSize(Size, isPCRel); } @@ -1566,17 +1572,8 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS, EmitImmediate(MCOperand::CreateImm(RegNum), MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups); } else { - unsigned FixupKind; - // FIXME: Is there a better way to know that we need a signed relocation? - if (MI.getOpcode() == X86::ADD64ri32 || - MI.getOpcode() == X86::MOV64ri32 || - MI.getOpcode() == X86::MOV64mi32 || - MI.getOpcode() == X86::PUSH64i32) - FixupKind = X86::reloc_signed_4byte; - else - FixupKind = getImmFixupKind(TSFlags); EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(), - X86II::getSizeOfImm(TSFlags), MCFixupKind(FixupKind), + X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags), CurByte, OS, Fixups); } } diff --git a/lib/Target/X86/X86InstrArithmetic.td b/lib/Target/X86/X86InstrArithmetic.td index 184e1ce418..cbc00abaf3 100644 --- a/lib/Target/X86/X86InstrArithmetic.td +++ b/lib/Target/X86/X86InstrArithmetic.td @@ -229,10 +229,10 @@ def IMUL32rri8 : Ii8<0x6B, MRMSrcReg, // GR32 = GR32*I8 [(set GR32:$dst, EFLAGS, (X86smul_flag GR32:$src1, i32immSExt8:$src2))], IIC_IMUL32_RRI>, OpSize16; -def IMUL64rri32 : RIi32<0x69, MRMSrcReg, // GR64 = GR64*I32 - (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2), - "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}", - [(set GR64:$dst, EFLAGS, +def IMUL64rri32 : RIi32S<0x69, MRMSrcReg, // GR64 = GR64*I32 + (outs GR64:$dst), (ins GR64:$src1, i64i32imm:$src2), + "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}", + [(set GR64:$dst, EFLAGS, (X86smul_flag GR64:$src1, i64immSExt32:$src2))], IIC_IMUL64_RRI>; def IMUL64rri8 : RIi8<0x6B, MRMSrcReg, // GR64 = GR64*I8 @@ -272,10 +272,10 @@ def IMUL32rmi8 : Ii8<0x6B, MRMSrcMem, // GR32 = [mem32]*I8 (X86smul_flag (load addr:$src1), i32immSExt8:$src2))], IIC_IMUL32_RMI>, OpSize16; -def IMUL64rmi32 : RIi32<0x69, MRMSrcMem, // GR64 = [mem64]*I32 - (outs GR64:$dst), (ins i64mem:$src1, i64i32imm:$src2), - "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}", - [(set GR64:$dst, EFLAGS, +def IMUL64rmi32 : RIi32S<0x69, MRMSrcMem, // GR64 = [mem64]*I32 + (outs GR64:$dst), (ins i64mem:$src1, i64i32imm:$src2), + "imul{q}\t{$src2, $src1, $dst|$dst, $src1, $src2}", + [(set GR64:$dst, EFLAGS, (X86smul_flag (load addr:$src1), i64immSExt32:$src2))], IIC_IMUL64_RMI>; @@ -681,7 +681,7 @@ def Xi32 : X86TypeInfo<i32, "l", GR32, loadi32, i32mem, Imm32, i32imm, imm, i32i8imm, i32immSExt8, 1, 0, 1, 0>; def Xi64 : X86TypeInfo<i64, "q", GR64, loadi64, i64mem, - Imm32, i64i32imm, i64immSExt32, i64i8imm, i64immSExt8, + Imm32S, i64i32imm, i64immSExt32, i64i8imm, i64immSExt8, 1, 0, 0, 1>; /// ITy - This instruction base class takes the type info for the instruction. diff --git a/lib/Target/X86/X86InstrFormats.td b/lib/Target/X86/X86InstrFormats.td index adc24e2318..ded1d90337 100644 --- a/lib/Target/X86/X86InstrFormats.td +++ b/lib/Target/X86/X86InstrFormats.td @@ -61,8 +61,8 @@ def MRM_DF : Format<59>; // ImmType - This specifies the immediate type used by an instruction. This is // part of the ad-hoc solution used to emit machine instruction encodings by our // machine code emitter. -class ImmType<bits<3> val> { - bits<3> Value = val; +class ImmType<bits<4> val> { + bits<4> Value = val; } def NoImm : ImmType<0>; def Imm8 : ImmType<1>; @@ -71,7 +71,8 @@ def Imm16 : ImmType<3>; def Imm16PCRel : ImmType<4>; def Imm32 : ImmType<5>; def Imm32PCRel : ImmType<6>; -def Imm64 : ImmType<7>; +def Imm32S : ImmType<7>; +def Imm64 : ImmType<8>; // FPFormat - This specifies what form this FP instruction has. This is used by // the Floating-Point stackifier pass. @@ -232,29 +233,29 @@ class X86Inst<bits<8> opcod, Format f, ImmType i, dag outs, dag ins, let TSFlags{8} = hasAdSizePrefix; let TSFlags{13-9} = Prefix; let TSFlags{14} = hasREX_WPrefix; - let TSFlags{17-15} = ImmT.Value; - let TSFlags{20-18} = FPForm.Value; - let TSFlags{21} = hasLockPrefix; - let TSFlags{23-22} = ExeDomain.Value; - let TSFlags{31-24} = Opcode; - let TSFlags{32} = hasVEXPrefix; - let TSFlags{33} = hasVEX_WPrefix; - let TSFlags{34} = hasVEX_4VPrefix; - let TSFlags{35} = hasVEX_4VOp3Prefix; - let TSFlags{36} = hasVEX_i8ImmReg; - let TSFlags{37} = hasVEX_L; - let TSFlags{38} = ignoresVEX_L; - let TSFlags{39} = hasEVEXPrefix; - let TSFlags{40} = hasEVEX_K; - let TSFlags{41} = hasEVEX_Z; - let TSFlags{42} = hasEVEX_L2; - let TSFlags{43} = hasEVEX_B; - let TSFlags{45-44} = EVEX_CD8E; - let TSFlags{48-46} = EVEX_CD8V; - let TSFlags{49} = has3DNow0F0FOpcode; - let TSFlags{50} = hasMemOp4Prefix; - let TSFlags{51} = hasXOP_Prefix; - let TSFlags{52} = hasEVEX_RC; + let TSFlags{18-15} = ImmT.Value; + let TSFlags{21-19} = FPForm.Value; + let TSFlags{22} = hasLockPrefix; + let TSFlags{24-23} = ExeDomain.Value; + let TSFlags{32-25} = Opcode; + let TSFlags{33} = hasVEXPrefix; + let TSFlags{34} = hasVEX_WPrefix; + let TSFlags{35} = hasVEX_4VPrefix; + let TSFlags{36} = hasVEX_4VOp3Prefix; + let TSFlags{37} = hasVEX_i8ImmReg; + let TSFlags{38} = hasVEX_L; + let TSFlags{39} = ignoresVEX_L; + let TSFlags{40} = hasEVEXPrefix; + let TSFlags{41} = hasEVEX_K; + let TSFlags{42} = hasEVEX_Z; + let TSFlags{43} = hasEVEX_L2; + let TSFlags{44} = hasEVEX_B; + let TSFlags{46-45} = EVEX_CD8E; + let TSFlags{49-47} = EVEX_CD8V; + let TSFlags{50} = has3DNow0F0FOpcode; + let TSFlags{51} = hasMemOp4Prefix; + let TSFlags{52} = hasXOP_Prefix; + let TSFlags{53} = hasEVEX_RC; } class PseudoI<dag oops, dag iops, list<dag> pattern> @@ -294,6 +295,12 @@ class Ii32<bits<8> o, Format f, dag outs, dag ins, string asm, let Pattern = pattern; let CodeSize = 3; } +class Ii32S<bits<8> o, Format f, dag outs, dag ins, string asm, + list<dag> pattern, InstrItinClass itin = NoItinerary> + : X86Inst<o, f, Imm32S, outs, ins, asm, itin> { + let Pattern = pattern; + let CodeSize = 3; +} class Ii16PCRel<bits<8> o, Format f, dag outs, dag ins, string asm, list<dag> pattern, InstrItinClass itin = NoItinerary> @@ -743,6 +750,9 @@ class RIi16 <bits<8> o, Format F, dag outs, dag ins, string asm, class RIi32 <bits<8> o, Format F, dag outs, dag ins, string asm, list<dag> pattern, InstrItinClass itin = NoItinerary> : Ii32<o, F, outs, ins, asm, pattern, itin>, REX_W; +class RIi32S <bits<8> o, Format F, dag outs, dag ins, string asm, + list<dag> pattern, InstrItinClass itin = NoItinerary> + : Ii32S<o, F, outs, ins, asm, pattern, itin>, REX_W; class RIi64<bits<8> o, Format f, dag outs, dag ins, string asm, list<dag> pattern, InstrItinClass itin = NoItinerary> diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index 2885bb54fc..35709133a2 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -1039,7 +1039,7 @@ def PUSH64i8 : Ii8<0x6a, RawFrm, (outs), (ins i64i8imm:$imm), def PUSH64i16 : Ii16<0x68, RawFrm, (outs), (ins i16imm:$imm), "push{w}\t$imm", [], IIC_PUSH_IMM>, OpSize, Requires<[In64BitMode]>; -def PUSH64i32 : Ii32<0x68, RawFrm, (outs), (ins i64i32imm:$imm), +def PUSH64i32 : Ii32S<0x68, RawFrm, (outs), (ins i64i32imm:$imm), "push{q}\t$imm", [], IIC_PUSH_IMM>, Requires<[In64BitMode]>; } @@ -1208,9 +1208,9 @@ def MOV32ri : Ii32<0xB8, AddRegFrm, (outs GR32:$dst), (ins i32imm:$src), def MOV64ri : RIi64<0xB8, AddRegFrm, (outs GR64:$dst), (ins i64imm:$src), "movabs{q}\t{$src, $dst|$dst, $src}", [(set GR64:$dst, imm:$src)], IIC_MOV>; -def MOV64ri32 : RIi32<0xC7, MRM0r, (outs GR64:$dst), (ins i64i32imm:$src), - "mov{q}\t{$src, $dst|$dst, $src}", - [(set GR64:$dst, i64immSExt32:$src)], IIC_MOV>; +def MOV64ri32 : RIi32S<0xC7, MRM0r, (outs GR64:$dst), (ins i64i32imm:$src), + "mov{q}\t{$src, $dst|$dst, $src}", + [(set GR64:$dst, i64immSExt32:$src)], IIC_MOV>; } } // SchedRW @@ -1224,9 +1224,9 @@ def MOV16mi : Ii16<0xC7, MRM0m, (outs), (ins i16mem:$dst, i16imm:$src), def MOV32mi : Ii32<0xC7, MRM0m, (outs), (ins i32mem:$dst, i32imm:$src), "mov{l}\t{$src, $dst|$dst, $src}", [(store (i32 imm:$src), addr:$dst)], IIC_MOV_MEM>, OpSize16; -def MOV64mi32 : RIi32<0xC7, MRM0m, (outs), (ins i64mem:$dst, i64i32imm:$src), - "mov{q}\t{$src, $dst|$dst, $src}", - [(store i64immSExt32:$src, addr:$dst)], IIC_MOV_MEM>; +def MOV64mi32 : RIi32S<0xC7, MRM0m, (outs), (ins i64mem:$dst, i64i32imm:$src), + "mov{q}\t{$src, $dst|$dst, $src}", + [(store i64immSExt32:$src, addr:$dst)], IIC_MOV_MEM>; } // SchedRW let hasSideEffects = 0 in { @@ -2100,6 +2100,7 @@ multiclass tbm_ternary_imm_intr<bits<8> opc, RegisterClass RC, string OpcodeStr, defm BEXTRI32 : tbm_ternary_imm_intr<0x10, GR32, "bextr", i32mem, loadi32, int_x86_tbm_bextri_u32, i32imm, imm>; +let ImmT = Imm32S in defm BEXTRI64 : tbm_ternary_imm_intr<0x10, GR64, "bextr", i64mem, loadi64, int_x86_tbm_bextri_u64, i64i32imm, i64immSExt32>, VEX_W; |