[mips] Range check simm32 and fold MIPS16's imm32 into simm32.

Summary:
At this point we should be able to enable IAS by default for O32 without
breaking check-all, or recursion.

Reviewers: vkalintiris

Subscribers: dsanders, llvm-commits

Differential Revision: http://reviews.llvm.org/D18439

llvm-svn: 265302
This commit is contained in:
Daniel Sanders 2016-04-04 15:32:49 +00:00
parent cacd94e242
commit b3c2764f89
4 changed files with 73 additions and 51 deletions

View File

@ -3815,6 +3815,10 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
case Match_UImm26_0: case Match_UImm26_0:
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
"expected 26-bit unsigned immediate"); "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: case Match_MemSImm9:
return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
"expected memory with 9-bit signed offset"); "expected memory with 9-bit signed offset");

View File

@ -483,13 +483,11 @@ class SelT<string op1, string op2>:
// //
// 32 bit constant // 32 bit constant
// //
def imm32: Operand<i32>;
def Constant32: def Constant32:
MipsPseudo16<(outs), (ins imm32:$imm), "\t.word $imm", []>; MipsPseudo16<(outs), (ins simm32:$imm), "\t.word $imm", []>;
def LwConstant32: 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:", []>; "lw\t$rx, 1f\n\tb\t2f\n\t.align\t2\n1: \t.word\t$imm\n2:", []>;

View File

@ -462,8 +462,16 @@ class UImmAsmOperandClass<int Bits, list<AsmOperandClass> Supers = []>
// uimm5 < uimm5_64, and uimm5 < vsplat_uimm5 // uimm5 < uimm5_64, and uimm5 < vsplat_uimm5
// This is entirely arbitrary. We need an ordering and what we pick is // This is entirely arbitrary. We need an ordering and what we pick is
// unimportant since only one is possible for a given mnemonic. // 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 def ConstantUImm26AsmOperandClass
: ConstantUImmAsmOperandClass<26, []>; : ConstantUImmAsmOperandClass<26, [SImm32AsmOperandClass]>;
def ConstantUImm20AsmOperandClass def ConstantUImm20AsmOperandClass
: ConstantUImmAsmOperandClass<20, [ConstantUImm26AsmOperandClass]>; : ConstantUImmAsmOperandClass<20, [ConstantUImm26AsmOperandClass]>;
def UImm16RelaxedAsmOperandClass def UImm16RelaxedAsmOperandClass
@ -629,8 +637,6 @@ def simm18_lsl3 : Operand<i32> {
let ParserMatchClass = MipsJumpTargetAsmOperand; let ParserMatchClass = MipsJumpTargetAsmOperand;
} }
def simm32 : Operand<i32>;
// Zero // Zero
def uimmz : Operand<i32> { def uimmz : Operand<i32> {
let PrintMethod = "printUImm<0>"; let PrintMethod = "printUImm<0>";
@ -805,9 +811,10 @@ def simm7_lsl2 : Operand<OtherVT> {
let ParserMatchClass = ConstantSImm7Lsl2AsmOperandClass; let ParserMatchClass = ConstantSImm7Lsl2AsmOperandClass;
} }
def simm16 : Operand<i32> { foreach I = {16, 32} in
let DecoderMethod = "DecodeSImmWithOffsetAndScale<16>"; def simm # I : Operand<i32> {
let ParserMatchClass = !cast<AsmOperandClass>("SImm16AsmOperandClass"); let DecoderMethod = "DecodeSImmWithOffsetAndScale<" # I # ">";
let ParserMatchClass = !cast<AsmOperandClass>("SImm" # I # "AsmOperandClass");
} }
// Like simm16 but coerces uimm16 to simm16. // Like simm16 but coerces uimm16 to simm16.
@ -821,6 +828,12 @@ def simm16_64 : Operand<i64> {
let ParserMatchClass = !cast<AsmOperandClass>("SImm16AsmOperandClass"); 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. // This is almost the same as a uimm7 but 0x7f is interpreted as -1.
def li16_imm : Operand<i32> { def li16_imm : Operand<i32> {
let DecoderMethod = "DecodeLi16Imm"; let DecoderMethod = "DecodeLi16Imm";
@ -2139,20 +2152,26 @@ def : MipsInstAlias<"move $dst, $src",
} }
def : MipsInstAlias<"bal $offset", (BGEZAL ZERO, brtarget:$offset), 0>, def : MipsInstAlias<"bal $offset", (BGEZAL ZERO, brtarget:$offset), 0>,
ISA_MIPS1_NOT_32R6_64R6; ISA_MIPS1_NOT_32R6_64R6;
def : MipsInstAlias<"addu $rs, $rt, $imm", def : MipsInstAlias<
(ADDiu GPR32Opnd:$rs, GPR32Opnd:$rt, simm32:$imm), 0>; "addu $rs, $rt, $imm",
def : MipsInstAlias<"addu $rs, $imm", (ADDiu GPR32Opnd:$rs, GPR32Opnd:$rt, simm32_relaxed:$imm), 0>;
(ADDiu GPR32Opnd:$rs, GPR32Opnd:$rs, simm32:$imm), 0>; def : MipsInstAlias<
def : MipsInstAlias<"add $rs, $rt, $imm", "addu $rs, $imm",
(ADDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32:$imm), 0>, (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; ISA_MIPS1_NOT_32R6_64R6;
def : MipsInstAlias<"add $rs, $imm", def : MipsInstAlias<
(ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm32:$imm), 0>, "add $rs, $imm",
(ADDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm32_relaxed:$imm), 0>,
ISA_MIPS1_NOT_32R6_64R6; ISA_MIPS1_NOT_32R6_64R6;
def : MipsInstAlias<"and $rs, $rt, $imm", def : MipsInstAlias<
(ANDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32:$imm), 0>; "and $rs, $rt, $imm",
def : MipsInstAlias<"and $rs, $imm", (ANDi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32_relaxed:$imm), 0>;
(ANDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm32:$imm), 0>; def : MipsInstAlias<
"and $rs, $imm",
(ANDi GPR32Opnd:$rs, GPR32Opnd:$rs, simm32_relaxed:$imm), 0>;
def : MipsInstAlias<"j $rs", (JR GPR32Opnd:$rs), 0>; def : MipsInstAlias<"j $rs", (JR GPR32Opnd:$rs), 0>;
let Predicates = [NotInMicroMips] in { let Predicates = [NotInMicroMips] in {
def : MipsInstAlias<"jalr $rs", (JALR RA, GPR32Opnd:$rs), 0>; def : MipsInstAlias<"jalr $rs", (JALR RA, GPR32Opnd:$rs), 0>;
@ -2166,18 +2185,24 @@ def : MipsInstAlias<"negu $rt",
(SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 0>; (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rt), 0>;
def : MipsInstAlias<"negu $rt, $rs", def : MipsInstAlias<"negu $rt, $rs",
(SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>; (SUBu GPR32Opnd:$rt, ZERO, GPR32Opnd:$rs), 1>;
def : MipsInstAlias<"slt $rs, $rt, $imm", def : MipsInstAlias<
(SLTi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32:$imm), 0>; "slt $rs, $rt, $imm",
def : MipsInstAlias<"sltu $rt, $rs, $imm", (SLTi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32_relaxed:$imm), 0>;
(SLTiu GPR32Opnd:$rt, GPR32Opnd:$rs, simm32:$imm), 0>; def : MipsInstAlias<
def : MipsInstAlias<"xor $rs, $rt, $imm", "sltu $rt, $rs, $imm",
(XORi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32:$imm), 0>; (SLTiu GPR32Opnd:$rt, GPR32Opnd:$rs, simm32_relaxed:$imm), 0>;
def : MipsInstAlias<"xor $rs, $imm", def : MipsInstAlias<
(XORi GPR32Opnd:$rs, GPR32Opnd:$rs, simm32:$imm), 0>; "xor $rs, $rt, $imm",
def : MipsInstAlias<"or $rs, $rt, $imm", (XORi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32_relaxed:$imm), 0>;
(ORi GPR32Opnd:$rs, GPR32Opnd:$rt, simm32:$imm), 0>; def : MipsInstAlias<
def : MipsInstAlias<"or $rs, $imm", "xor $rs, $imm",
(ORi GPR32Opnd:$rs, GPR32Opnd:$rs, simm32:$imm), 0>; (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 { let AdditionalPredicates = [NotInMicroMips] in {
def : MipsInstAlias<"nop", (SLL ZERO, ZERO, 0), 1>; def : MipsInstAlias<"nop", (SLL ZERO, ZERO, 0), 1>;
} }
@ -2242,10 +2267,11 @@ def : MipsInstAlias<"sync",
// Assembler Pseudo Instructions // 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> : class LoadImmediate32<string instr_asm, Operand Od, RegisterOperand RO> :
MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32), MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
!strconcat(instr_asm, "\t$rt, $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, class LoadAddressFromReg32<string instr_asm, Operand MemOpnd,
RegisterOperand RO> : RegisterOperand RO> :
@ -2256,7 +2282,7 @@ def LoadAddrReg32 : LoadAddressFromReg32<"la", mem, GPR32Opnd>;
class LoadAddressFromImm32<string instr_asm, Operand Od, RegisterOperand RO> : class LoadAddressFromImm32<string instr_asm, Operand Od, RegisterOperand RO> :
MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32), MipsAsmPseudoInst<(outs RO:$rt), (ins Od:$imm32),
!strconcat(instr_asm, "\t$rt, $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), def JalTwoReg : MipsAsmPseudoInst<(outs GPR32Opnd:$rd), (ins GPR32Opnd:$rs),
"jal\t$rd, $rs"> ; "jal\t$rd, $rs"> ;

View File

@ -22,8 +22,7 @@ text_label:
# CHECK: lui $1, 1 # encoding: [0x01,0x00,0x01,0x3c] # CHECK: lui $1, 1 # encoding: [0x01,0x00,0x01,0x3c]
# CHECK: add $4, $4, $1 # encoding: [0x20,0x20,0x81,0x00] # CHECK: add $4, $4, $1 # encoding: [0x20,0x20,0x81,0x00]
add $4, 0xFFFFFFFF add $4, 0xFFFFFFFF
# CHECK: addiu $1, $zero, -1 # encoding: [0xff,0xff,0x01,0x24] # CHECK: addi $4, $4, -1 # encoding: [0xff,0xff,0x84,0x20]
# CHECK: add $4, $4, $1 # encoding: [0x20,0x20,0x81,0x00]
add $4, $5, -0x80000000 add $4, $5, -0x80000000
# CHECK: lui $4, 32768 # encoding: [0x00,0x80,0x04,0x3c] # 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: lui $4, 1 # encoding: [0x01,0x00,0x04,0x3c]
# CHECK: add $4, $4, $5 # encoding: [0x20,0x20,0x85,0x00] # CHECK: add $4, $4, $5 # encoding: [0x20,0x20,0x85,0x00]
add $4, $5, 0xFFFFFFFF add $4, $5, 0xFFFFFFFF
# CHECK: addiu $4, $zero, -1 # encoding: [0xff,0xff,0x04,0x24] # CHECK: addi $4, $5, -1 # encoding: [0xff,0xff,0xa4,0x20]
# CHECK: add $4, $4, $5 # encoding: [0x20,0x20,0x85,0x00]
addu $4, -0x80000000 addu $4, -0x80000000
# CHECK: lui $1, 32768 # encoding: [0x00,0x80,0x01,0x3c] # 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: lui $1, 1 # encoding: [0x01,0x00,0x01,0x3c]
# CHECK: addu $4, $4, $1 # encoding: [0x21,0x20,0x81,0x00] # CHECK: addu $4, $4, $1 # encoding: [0x21,0x20,0x81,0x00]
addu $4, 0xFFFFFFFF addu $4, 0xFFFFFFFF
# CHECK: addiu $1, $zero, -1 # encoding: [0xff,0xff,0x01,0x24] # CHECK: addiu $4, $4, -1 # encoding: [0xff,0xff,0x84,0x24]
# CHECK: addu $4, $4, $1 # encoding: [0x21,0x20,0x81,0x00]
addu $4, $5, -0x80000000 addu $4, $5, -0x80000000
# CHECK: lui $4, 32768 # encoding: [0x00,0x80,0x04,0x3c] # 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: lui $4, 1 # encoding: [0x01,0x00,0x04,0x3c]
# CHECK: addu $4, $4, $5 # encoding: [0x21,0x20,0x85,0x00] # CHECK: addu $4, $4, $5 # encoding: [0x21,0x20,0x85,0x00]
addu $4, $5, 0xFFFFFFFF addu $4, $5, 0xFFFFFFFF
# CHECK: addiu $4, $zero, -1 # encoding: [0xff,0xff,0x04,0x24] # CHECK: addiu $4, $5, -1 # encoding: [0xff,0xff,0xa4,0x24]
# CHECK: addu $4, $4, $5 # encoding: [0x21,0x20,0x85,0x00]
and $4, -0x80000000 and $4, -0x80000000
# CHECK: lui $1, 32768 # encoding: [0x00,0x80,0x01,0x3c] # 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: lui $4, 1 # encoding: [0x01,0x00,0x04,0x3c]
# CHECK: slt $4, $4, $5 # encoding: [0x2a,0x20,0x85,0x00] # CHECK: slt $4, $4, $5 # encoding: [0x2a,0x20,0x85,0x00]
slt $4, $5, 0xFFFFFFFF slt $4, $5, 0xFFFFFFFF
# CHECK: addiu $4, $zero, -1 # encoding: [0xff,0xff,0x04,0x24] # CHECK: slti $4, $5, -1 # encoding: [0xff,0xff,0xa4,0x28]
# CHECK: slt $4, $4, $5 # encoding: [0x2a,0x20,0x85,0x00]
sltu $4, $5, -0x80000000 sltu $4, $5, -0x80000000
# CHECK: lui $4, 32768 # encoding: [0x00,0x80,0x04,0x3c] # 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: lui $4, 1 # encoding: [0x01,0x00,0x04,0x3c]
# CHECK: sltu $4, $4, $5 # encoding: [0x2b,0x20,0x85,0x00] # CHECK: sltu $4, $4, $5 # encoding: [0x2b,0x20,0x85,0x00]
sltu $4, $5, 0xFFFFFFFF sltu $4, $5, 0xFFFFFFFF
# CHECK: addiu $4, $zero, -1 # encoding: [0xff,0xff,0x04,0x24] # CHECK: sltiu $4, $5, -1 # encoding: [0xff,0xff,0xa4,0x2c]
# CHECK: sltu $4, $4, $5 # encoding: [0x2b,0x20,0x85,0x00]
xor $4, -0x80000000 xor $4, -0x80000000
# CHECK: lui $1, 32768 # encoding: [0x00,0x80,0x01,0x3c] # CHECK: lui $1, 32768 # encoding: [0x00,0x80,0x01,0x3c]