diff options
-rw-r--r-- | llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/Mips16InstrInfo.td | 6 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MipsInstrInfo.td | 96 | ||||
-rw-r--r-- | llvm/test/MC/Mips/instalias-imm-expanding.s | 18 |
4 files changed, 73 insertions, 51 deletions
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 2d98fa02e11..011727a88c8 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -3815,6 +3815,10 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, case Match_UImm26_0: return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected 26-bit unsigned immediate"); + case Match_SImm32: + case Match_SImm32_Relaxed: + return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), + "expected 32-bit signed immediate"); case Match_MemSImm9: return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected memory with 9-bit signed offset"); diff --git a/llvm/lib/Target/Mips/Mips16InstrInfo.td b/llvm/lib/Target/Mips/Mips16InstrInfo.td index ebb94e52f11..3b565b0fffb 100644 --- a/llvm/lib/Target/Mips/Mips16InstrInfo.td +++ b/llvm/lib/Target/Mips/Mips16InstrInfo.td @@ -483,13 +483,11 @@ class SelT<string op1, string op2>: // // 32 bit constant // -def imm32: Operand<i32>; - def Constant32: - MipsPseudo16<(outs), (ins imm32:$imm), "\t.word $imm", []>; + MipsPseudo16<(outs), (ins simm32:$imm), "\t.word $imm", []>; def LwConstant32: - MipsPseudo16<(outs CPU16Regs:$rx), (ins imm32:$imm, imm32:$constid), + MipsPseudo16<(outs CPU16Regs:$rx), (ins simm32:$imm, simm32:$constid), "lw\t$rx, 1f\n\tb\t2f\n\t.align\t2\n1: \t.word\t$imm\n2:", []>; diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.td b/llvm/lib/Target/Mips/MipsInstrInfo.td index de8683b7308..d2699133edb 100644 --- a/llvm/lib/Target/Mips/MipsInstrInfo.td +++ b/llvm/lib/Target/Mips/MipsInstrInfo.td @@ -462,8 +462,16 @@ class UImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []> // uimm5 < uimm5_64, and uimm5 < vsplat_uimm5 // This is entirely arbitrary. We need an ordering and what we pick is // unimportant since only one is possible for a given mnemonic. +def SImm32RelaxedAsmOperandClass + : SImmAsmOperandClass<32, []> { + let Name = "SImm32_Relaxed"; + let PredicateMethod = "isAnyImm<32>"; + let DiagnosticType = "SImm32_Relaxed"; +} +def SImm32AsmOperandClass + : SImmAsmOperandClass<32, [SImm32RelaxedAsmOperandClass]>; def ConstantUImm26AsmOperandClass - : ConstantUImmAsmOperandClass<26, []>; + : ConstantUImmAsmOperandClass<26, [SImm32AsmOperandClass]>; def ConstantUImm20AsmOperandClass : ConstantUImmAsmOperandClass<20, [ConstantUImm26AsmOperandClass]>; def UImm16RelaxedAsmOperandClass @@ -629,8 +637,6 @@ def simm18_lsl3 : Operand<i32> { let ParserMatchClass = MipsJumpTargetAsmOperand; } -def simm32 : Operand<i32>; - // Zero def uimmz : Operand<i32> { let PrintMethod = "printUImm<0>"; @@ -805,10 +811,11 @@ def simm7_lsl2 : Operand<OtherVT> { let ParserMatchClass = ConstantSImm7Lsl2AsmOperandClass; } -def simm16 : Operand<i32> { - let DecoderMethod = "DecodeSImmWithOffsetAndScale<16>"; - let ParserMatchClass = !cast<AsmOperandClass>("SImm16AsmOperandClass"); -} +foreach I = {16, 32} in + def simm # I : Operand<i32> { + let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">"; + let ParserMatchClass = !cast<AsmOperandClass>("SImm" # I # "AsmOperandClass"); + } // Like simm16 but coerces uimm16 to simm16. def simm16_relaxed : Operand<i32> { @@ -821,6 +828,12 @@ def simm16_64 : Operand<i64> { let ParserMatchClass = !cast<AsmOperandClass>("SImm16AsmOperandClass"); } +// Like simm32 but coerces uimm32 to simm32. +def simm32_relaxed : Operand<i32> { + let DecoderMethod = "DecodeSImmWithOffsetAndScale<32>"; + let ParserMatchClass = !cast<AsmOperandClass>("SImm32RelaxedAsmOperandClass"); +} + // This is almost the same as a uimm7 but 0x7f is interpreted as -1. def li16_imm : Operand<i32> { let DecoderMethod = "DecodeLi16Imm"; @@ -2139,20 +2152,26 @@ def : MipsInstAlias<"move $dst, $src", } def : MipsInstAlias<"bal $offset", (BGEZAL ZERO, brtarget:$offset), 0>, ISA_MIPS1_NOT_32R6_64R6; -def : MipsInstAlias<"addu $rs, $rt, $imm", - (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rt, simm32:$imm), 0>; -def : MipsInstAlias<"addu $rs, $imm", - (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs, simm32:$imm), 0>; -def : MipsInstAlias<"add $rs, $rt, $imm", - (ADDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32:$imm), 0>, - ISA_MIPS1_NOT_32R6_64R6; -def : MipsInstAlias<"add $rs, $imm", - (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm32:$imm), 0>, - ISA_MIPS1_NOT_32R6_64R6; -def : MipsInstAlias<"and $rs, $rt, $imm", - (ANDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32:$imm), 0>; -def : MipsInstAlias<"and $rs, $imm", - (ANDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm32:$imm), 0>; +def : MipsInstAlias< + "addu $rs, $rt, $imm", + (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rt, simm32_relaxed:$imm), 0>; +def : MipsInstAlias< + "addu $rs, $imm", + (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs, simm32_relaxed:$imm), 0>; +def : MipsInstAlias< + "add $rs, $rt, $imm", + (ADDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32_relaxed:$imm), 0>, + ISA_MIPS1_NOT_32R6_64R6; +def : MipsInstAlias< + "add $rs, $imm", + (ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm32_relaxed:$imm), 0>, + ISA_MIPS1_NOT_32R6_64R6; +def : MipsInstAlias< + "and $rs, $rt, $imm", + (ANDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32_relaxed:$imm), 0>; +def : MipsInstAlias< + "and $rs, $imm", + (ANDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm32_relaxed:$imm), 0>; def : MipsInstAlias<"j $rs", (JR GPR32Opnd:$rs), 0>; let Predicates = [NotInMicroMips] in { def : MipsInstAlias<"jalr $rs", (JALR RA, GPR32Opnd:$rs), 0>; @@ -2166,18 +2185,24 @@ def : MipsInstAlias<"negu $rt", (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 0>; def : MipsInstAlias<"negu $rt, $rs", (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>; -def : MipsInstAlias<"slt $rs, $rt, $imm", - (SLTi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32:$imm), 0>; -def : MipsInstAlias<"sltu $rt, $rs, $imm", - (SLTiu GPR32Opnd:$rt, GPR32Opnd:$rs, simm32:$imm), 0>; -def : MipsInstAlias<"xor $rs, $rt, $imm", - (XORi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32:$imm), 0>; -def : MipsInstAlias<"xor $rs, $imm", - (XORi GPR32Opnd:$rs, GPR32Opnd:$rs, simm32:$imm), 0>; -def : MipsInstAlias<"or $rs, $rt, $imm", - (ORi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32:$imm), 0>; -def : MipsInstAlias<"or $rs, $imm", - (ORi GPR32Opnd:$rs, GPR32Opnd:$rs, simm32:$imm), 0>; +def : MipsInstAlias< + "slt $rs, $rt, $imm", + (SLTi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32_relaxed:$imm), 0>; +def : MipsInstAlias< + "sltu $rt, $rs, $imm", + (SLTiu GPR32Opnd:$rt, GPR32Opnd:$rs, simm32_relaxed:$imm), 0>; +def : MipsInstAlias< + "xor $rs, $rt, $imm", + (XORi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32_relaxed:$imm), 0>; +def : MipsInstAlias< + "xor $rs, $imm", + (XORi GPR32Opnd:$rs, GPR32Opnd:$rs, simm32_relaxed:$imm), 0>; +def : MipsInstAlias< + "or $rs, $rt, $imm", + (ORi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32_relaxed:$imm), 0>; +def : MipsInstAlias< + "or $rs, $imm", + (ORi GPR32Opnd:$rs, GPR32Opnd:$rs, simm32_relaxed:$imm), 0>; let AdditionalPredicates = [NotInMicroMips] in { def : MipsInstAlias<"nop", (SLL ZERO, ZERO, 0), 1>; } @@ -2242,10 +2267,11 @@ def : MipsInstAlias<"sync", // Assembler Pseudo Instructions //===----------------------------------------------------------------------===// +// We use i32imm on li/la to defer range checking to the assembler. class LoadImmediate32<string instr_asm, Operand Od, RegisterOperand RO> : MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32), !strconcat(instr_asm, "\t$rt, $imm32")> ; -def LoadImm32 : LoadImmediate32<"li", simm32, GPR32Opnd>; +def LoadImm32 : LoadImmediate32<"li", i32imm, GPR32Opnd>; class LoadAddressFromReg32<string instr_asm, Operand MemOpnd, RegisterOperand RO> : @@ -2256,7 +2282,7 @@ def LoadAddrReg32 : LoadAddressFromReg32<"la", mem, GPR32Opnd>; class LoadAddressFromImm32<string instr_asm, Operand Od, RegisterOperand RO> : MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32), !strconcat(instr_asm, "\t$rt, $imm32")> ; -def LoadAddrImm32 : LoadAddressFromImm32<"la", simm32, GPR32Opnd>; +def LoadAddrImm32 : LoadAddressFromImm32<"la", i32imm, GPR32Opnd>; def JalTwoReg : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs), "jal\t$rd, $rs"> ; diff --git a/llvm/test/MC/Mips/instalias-imm-expanding.s b/llvm/test/MC/Mips/instalias-imm-expanding.s index b3667ef8bf8..9759dabdc08 100644 --- a/llvm/test/MC/Mips/instalias-imm-expanding.s +++ b/llvm/test/MC/Mips/instalias-imm-expanding.s @@ -22,8 +22,7 @@ text_label: # CHECK: lui $1, 1 # encoding: [0x01,0x00,0x01,0x3c] # CHECK: add $4, $4, $1 # encoding: [0x20,0x20,0x81,0x00] add $4, 0xFFFFFFFF -# CHECK: addiu $1, $zero, -1 # encoding: [0xff,0xff,0x01,0x24] -# CHECK: add $4, $4, $1 # encoding: [0x20,0x20,0x81,0x00] +# CHECK: addi $4, $4, -1 # encoding: [0xff,0xff,0x84,0x20] add $4, $5, -0x80000000 # CHECK: lui $4, 32768 # encoding: [0x00,0x80,0x04,0x3c] @@ -43,8 +42,7 @@ text_label: # CHECK: lui $4, 1 # encoding: [0x01,0x00,0x04,0x3c] # CHECK: add $4, $4, $5 # encoding: [0x20,0x20,0x85,0x00] add $4, $5, 0xFFFFFFFF -# CHECK: addiu $4, $zero, -1 # encoding: [0xff,0xff,0x04,0x24] -# CHECK: add $4, $4, $5 # encoding: [0x20,0x20,0x85,0x00] +# CHECK: addi $4, $5, -1 # encoding: [0xff,0xff,0xa4,0x20] addu $4, -0x80000000 # CHECK: lui $1, 32768 # encoding: [0x00,0x80,0x01,0x3c] @@ -64,8 +62,7 @@ text_label: # CHECK: lui $1, 1 # encoding: [0x01,0x00,0x01,0x3c] # CHECK: addu $4, $4, $1 # encoding: [0x21,0x20,0x81,0x00] addu $4, 0xFFFFFFFF -# CHECK: addiu $1, $zero, -1 # encoding: [0xff,0xff,0x01,0x24] -# CHECK: addu $4, $4, $1 # encoding: [0x21,0x20,0x81,0x00] +# CHECK: addiu $4, $4, -1 # encoding: [0xff,0xff,0x84,0x24] addu $4, $5, -0x80000000 # CHECK: lui $4, 32768 # encoding: [0x00,0x80,0x04,0x3c] @@ -85,8 +82,7 @@ text_label: # CHECK: lui $4, 1 # encoding: [0x01,0x00,0x04,0x3c] # CHECK: addu $4, $4, $5 # encoding: [0x21,0x20,0x85,0x00] addu $4, $5, 0xFFFFFFFF -# CHECK: addiu $4, $zero, -1 # encoding: [0xff,0xff,0x04,0x24] -# CHECK: addu $4, $4, $5 # encoding: [0x21,0x20,0x85,0x00] +# CHECK: addiu $4, $5, -1 # encoding: [0xff,0xff,0xa4,0x24] and $4, -0x80000000 # CHECK: lui $1, 32768 # encoding: [0x00,0x80,0x01,0x3c] @@ -208,8 +204,7 @@ text_label: # CHECK: lui $4, 1 # encoding: [0x01,0x00,0x04,0x3c] # CHECK: slt $4, $4, $5 # encoding: [0x2a,0x20,0x85,0x00] slt $4, $5, 0xFFFFFFFF -# CHECK: addiu $4, $zero, -1 # encoding: [0xff,0xff,0x04,0x24] -# CHECK: slt $4, $4, $5 # encoding: [0x2a,0x20,0x85,0x00] +# CHECK: slti $4, $5, -1 # encoding: [0xff,0xff,0xa4,0x28] sltu $4, $5, -0x80000000 # CHECK: lui $4, 32768 # encoding: [0x00,0x80,0x04,0x3c] @@ -228,8 +223,7 @@ text_label: # CHECK: lui $4, 1 # encoding: [0x01,0x00,0x04,0x3c] # CHECK: sltu $4, $4, $5 # encoding: [0x2b,0x20,0x85,0x00] sltu $4, $5, 0xFFFFFFFF -# CHECK: addiu $4, $zero, -1 # encoding: [0xff,0xff,0x04,0x24] -# CHECK: sltu $4, $4, $5 # encoding: [0x2b,0x20,0x85,0x00] +# CHECK: sltiu $4, $5, -1 # encoding: [0xff,0xff,0xa4,0x2c] xor $4, -0x80000000 # CHECK: lui $1, 32768 # encoding: [0x00,0x80,0x01,0x3c] |