diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/X86/AsmParser/X86AsmParser.cpp | 85 | ||||
-rw-r--r-- | lib/Target/X86/X86Instr64bit.td | 4 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrInfo.td | 39 |
3 files changed, 90 insertions, 38 deletions
diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp index b291ef6..25ec6ce 100644 --- a/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -186,32 +186,71 @@ struct X86Operand : public MCParsedAsmOperand { bool isImm() const { return Kind == Immediate; } - bool isImmSExt8() const { - // Accept immediates which fit in 8 bits when sign extended, and - // non-absolute immediates. + bool isImmSExti16i8() const { if (!isImm()) return false; - if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm())) { - int64_t Value = CE->getValue(); - return Value == (int64_t) (int8_t) Value; - } + // If this isn't a constant expr, just assume it fits and let relaxation + // handle it. + const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); + if (!CE) + return true; - return true; + // Otherwise, check the value is in a range that makes sense for this + // extension. + uint64_t Value = CE->getValue(); + return (( Value <= 0x000000000000007FULL)|| + (0x000000000000FF80ULL <= Value && Value <= 0x000000000000FFFFULL)|| + (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL)); } - - bool isImmSExt32() const { - // Accept immediates which fit in 32 bits when sign extended, and - // non-absolute immediates. + bool isImmSExti32i8() const { if (!isImm()) return false; - if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm())) { - int64_t Value = CE->getValue(); - return Value == (int64_t) (int32_t) Value; - } + // If this isn't a constant expr, just assume it fits and let relaxation + // handle it. + const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); + if (!CE) + return true; - return true; + // Otherwise, check the value is in a range that makes sense for this + // extension. + uint64_t Value = CE->getValue(); + return (( Value <= 0x000000000000007FULL)|| + (0x00000000FFFFFF80ULL <= Value && Value <= 0x00000000FFFFFFFFULL)|| + (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL)); + } + bool isImmSExti64i8() const { + if (!isImm()) + return false; + + // If this isn't a constant expr, just assume it fits and let relaxation + // handle it. + const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); + if (!CE) + return true; + + // Otherwise, check the value is in a range that makes sense for this + // extension. + uint64_t Value = CE->getValue(); + return (( Value <= 0x000000000000007FULL)|| + (0xFFFFFFFFFFFFFF80ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL)); + } + bool isImmSExti64i32() const { + if (!isImm()) + return false; + + // If this isn't a constant expr, just assume it fits and let relaxation + // handle it. + const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm()); + if (!CE) + return true; + + // Otherwise, check the value is in a range that makes sense for this + // extension. + uint64_t Value = CE->getValue(); + return (( Value <= 0x000000007FFFFFFFULL)|| + (0xFFFFFFFF80000000ULL <= Value && Value <= 0xFFFFFFFFFFFFFFFFULL)); } bool isMem() const { return Kind == Memory; } @@ -245,18 +284,6 @@ struct X86Operand : public MCParsedAsmOperand { addExpr(Inst, getImm()); } - void addImmSExt8Operands(MCInst &Inst, unsigned N) const { - // FIXME: Support user customization of the render method. - assert(N == 1 && "Invalid number of operands!"); - addExpr(Inst, getImm()); - } - - void addImmSExt32Operands(MCInst &Inst, unsigned N) const { - // FIXME: Support user customization of the render method. - assert(N == 1 && "Invalid number of operands!"); - addExpr(Inst, getImm()); - } - void addMemOperands(MCInst &Inst, unsigned N) const { assert((N == 5) && "Invalid number of operands!"); Inst.addOperand(MCOperand::CreateReg(getMemBaseReg())); diff --git a/lib/Target/X86/X86Instr64bit.td b/lib/Target/X86/X86Instr64bit.td index 24a1296..f2919f5 100644 --- a/lib/Target/X86/X86Instr64bit.td +++ b/lib/Target/X86/X86Instr64bit.td @@ -19,7 +19,7 @@ // 64-bits but only 32 bits are significant. def i64i32imm : Operand<i64> { - let ParserMatchClass = ImmSExt32AsmOperand; + let ParserMatchClass = ImmSExti64i32AsmOperand; } // 64-bits but only 32 bits are significant, and those bits are treated as being @@ -32,7 +32,7 @@ def i64i32imm_pcrel : Operand<i64> { // 64-bits but only 8 bits are significant. def i64i8imm : Operand<i64> { - let ParserMatchClass = ImmSExt8AsmOperand; + let ParserMatchClass = ImmSExti64i8AsmOperand; } // Special i64mem for addresses of load folding tail calls. These are not diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td index 5a5535a..6e73766 100644 --- a/lib/Target/X86/X86InstrInfo.td +++ b/lib/Target/X86/X86InstrInfo.td @@ -270,24 +270,49 @@ def SSECC : Operand<i8> { let PrintMethod = "printSSECC"; } -def ImmSExt32AsmOperand : AsmOperandClass { - let Name = "ImmSExt32"; +class ImmSExtAsmOperandClass : AsmOperandClass { let SuperClasses = [ImmAsmOperand]; + let RenderMethod = "addImmOperands"; } -def ImmSExt8AsmOperand : AsmOperandClass { - let Name = "ImmSExt8"; - let SuperClasses = [ImmSExt32AsmOperand]; +// Sign-extended immediate classes. We don't need to define the full lattice +// here because there is no instruction with an ambiguity between ImmSExti64i32 +// and ImmSExti32i8. +// +// The strange ranges come from the fact that the assembler always works with +// 64-bit immediates, but for a 16-bit target value we want to accept both "-1" +// (which will be a -1ULL), and "0xFF" (-1 in 16-bits). + +// [0, 0x7FFFFFFF] | [0xFFFFFFFF80000000, 0xFFFFFFFFFFFFFFFF] +def ImmSExti64i32AsmOperand : ImmSExtAsmOperandClass { + let Name = "ImmSExti64i32"; +} + +// [0, 0x0000007F] | [0x000000000000FF80, 0x000000000000FFFF] | [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF] +def ImmSExti16i8AsmOperand : ImmSExtAsmOperandClass { + let Name = "ImmSExti16i8"; + let SuperClasses = [ImmSExti64i32AsmOperand]; +} + +// [0, 0x0000007F] | [0x00000000FFFFFF80, 0x00000000FFFFFFFF] | [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF] +def ImmSExti32i8AsmOperand : ImmSExtAsmOperandClass { + let Name = "ImmSExti32i8"; +} + +// [0, 0x0000007F] | [0xFFFFFFFFFFFFFF80, 0xFFFFFFFFFFFFFFFF] +def ImmSExti64i8AsmOperand : ImmSExtAsmOperandClass { + let Name = "ImmSExti64i8"; + let SuperClasses = [ImmSExti16i8AsmOperand, ImmSExti32i8AsmOperand, ImmSExti64i32AsmOperand]; } // A couple of more descriptive operand definitions. // 16-bits but only 8 bits are significant. def i16i8imm : Operand<i16> { - let ParserMatchClass = ImmSExt8AsmOperand; + let ParserMatchClass = ImmSExti16i8AsmOperand; } // 32-bits but only 8 bits are significant. def i32i8imm : Operand<i32> { - let ParserMatchClass = ImmSExt8AsmOperand; + let ParserMatchClass = ImmSExti32i8AsmOperand; } //===----------------------------------------------------------------------===// |