diff options
author | Simon Dardis <simon.dardis@imgtec.com> | 2017-02-24 14:34:32 +0000 |
---|---|---|
committer | Simon Dardis <simon.dardis@imgtec.com> | 2017-02-24 14:34:32 +0000 |
commit | aa208817498b0190806208b08b952a9d76223159 (patch) | |
tree | e9de0ac0946ef3526349aabadaa25652e0b789de /llvm/lib | |
parent | 29c1afb880fa399ebbfbde0c608dc86e504f6eec (diff) | |
download | bcm5719-llvm-aa208817498b0190806208b08b952a9d76223159.tar.gz bcm5719-llvm-aa208817498b0190806208b08b952a9d76223159.zip |
[mips] Handle 64 bit immediate in and/or/xor pseudo instructions on mips64
Previously LLVM was assuming 32-bit signed immediates which results in and with
a bitmask that has bit 31 set to incorrectly include bits 63-32 in the result.
After applying this patch I can now compile all of the FreeBSD mips assembly
code with clang.
This issue also affects the nor, slt and sltu macros and I will fix those in a
separate review.
Patch By: Alexander Richardson
Commit message reformatted by sdardis.
Reviewers: atanasyan, theraven, sdardis
Differential Revision: https://reviews.llvm.org/D30298
llvm-svn: 296125
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 18 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/Mips64InstrInfo.td | 9 | ||||
-rw-r--r-- | llvm/lib/Target/Mips/MipsInstrInfo.td | 22 |
3 files changed, 34 insertions, 15 deletions
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 2a69860a0fe..b79ad210389 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -2392,9 +2392,9 @@ MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, : MER_Success; } return MER_NotAMacro; - case Mips::ANDi: case Mips::ANDi_MM: - case Mips::ORi: case Mips::ORi_MM: - case Mips::XORi: case Mips::XORi_MM: + case Mips::ANDi: case Mips::ANDi_MM: case Mips::ANDi64: + case Mips::ORi: case Mips::ORi_MM: case Mips::ORi64: + case Mips::XORi: case Mips::XORi_MM: case Mips::XORi64: if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) { int64_t ImmValue = Inst.getOperand(2).getImm(); @@ -2581,7 +2581,6 @@ bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg, uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff; uint16_t Bits15To0 = ImmValue & 0xffff; - if (!Is32BitImm && !isInt<32>(ImmValue)) { // Traditional behaviour seems to special case this particular value. It's // not clear why other masks are handled differently. @@ -3805,7 +3804,7 @@ bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, unsigned SrcReg = Inst.getOperand(1).getReg(); int64_t ImmValue = Inst.getOperand(2).getImm(); - bool Is32Bit = isInt<32>(ImmValue) || isUInt<32>(ImmValue); + bool Is32Bit = isInt<32>(ImmValue) || (!isGP64bit() && isUInt<32>(ImmValue)); unsigned FinalOpcode = Inst.getOpcode(); @@ -3866,6 +3865,15 @@ bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, case Mips::XORi_MM: FinalOpcode = Mips::XOR_MM; break; + case Mips::ANDi64: + FinalOpcode = Mips::AND64; + break; + case Mips::ORi64: + FinalOpcode = Mips::OR64; + break; + case Mips::XORi64: + FinalOpcode = Mips::XOR64; + break; } if (FinalDstReg == Mips::NoRegister) diff --git a/llvm/lib/Target/Mips/Mips64InstrInfo.td b/llvm/lib/Target/Mips/Mips64InstrInfo.td index 7ce278e4bf4..87ab7920ede 100644 --- a/llvm/lib/Target/Mips/Mips64InstrInfo.td +++ b/llvm/lib/Target/Mips/Mips64InstrInfo.td @@ -707,6 +707,15 @@ let AdditionalPredicates = [NotInMicroMips] in { def : MipsInstAlias<"daddu $rs, $imm", (DADDiu GPR64Opnd:$rs, GPR64Opnd:$rs, simm16_64:$imm), 0>, ISA_MIPS3; + + defm : OneOrTwoOperandMacroImmediateAlias<"and", ANDi64, GPR64Opnd, imm64>, + GPR_64; + + defm : OneOrTwoOperandMacroImmediateAlias<"or", ORi64, GPR64Opnd, imm64>, + GPR_64; + + defm : OneOrTwoOperandMacroImmediateAlias<"xor", XORi64, GPR64Opnd, imm64>, + GPR_64; } def : MipsInstAlias<"dsll $rd, $rt, $rs", (DSLLV GPR64Opnd:$rd, GPR64Opnd:$rt, GPR32Opnd:$rs), 0>, diff --git a/llvm/lib/Target/Mips/MipsInstrInfo.td b/llvm/lib/Target/Mips/MipsInstrInfo.td index c84642773ae..d4b3052cc93 100644 --- a/llvm/lib/Target/Mips/MipsInstrInfo.td +++ b/llvm/lib/Target/Mips/MipsInstrInfo.td @@ -2322,15 +2322,17 @@ def MULOUMacro : MipsAsmPseudoInst<(outs), (ins GPR32Opnd:$rd, GPR32Opnd:$rs, //===----------------------------------------------------------------------===// multiclass OneOrTwoOperandMacroImmediateAlias<string Memnomic, - Instruction Opcode> { + Instruction Opcode, + RegisterOperand RO = GPR32Opnd, + Operand Imm = simm32_relaxed> { def : MipsInstAlias<!strconcat(Memnomic, " $rs, $rt, $imm"), - (Opcode GPR32Opnd:$rs, - GPR32Opnd:$rt, - simm32_relaxed:$imm), 0>; + (Opcode RO:$rs, + RO:$rt, + Imm:$imm), 0>; def : MipsInstAlias<!strconcat(Memnomic, " $rs, $imm"), - (Opcode GPR32Opnd:$rs, - GPR32Opnd:$rs, - simm32_relaxed:$imm), 0>; + (Opcode RO:$rs, + RO:$rs, + Imm:$imm), 0>; } def : MipsInstAlias<"move $dst, $src", @@ -2384,11 +2386,11 @@ let AdditionalPredicates = [NotInMicroMips] in { defm : OneOrTwoOperandMacroImmediateAlias<"addu", ADDiu>; - defm : OneOrTwoOperandMacroImmediateAlias<"and", ANDi>; + defm : OneOrTwoOperandMacroImmediateAlias<"and", ANDi>, GPR_32; - defm : OneOrTwoOperandMacroImmediateAlias<"or", ORi>; + defm : OneOrTwoOperandMacroImmediateAlias<"or", ORi>, GPR_32; - defm : OneOrTwoOperandMacroImmediateAlias<"xor", XORi>; + defm : OneOrTwoOperandMacroImmediateAlias<"xor", XORi>, GPR_32; defm : OneOrTwoOperandMacroImmediateAlias<"slt", SLTi>; |