mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-07 11:33:44 +00:00
[mips] [IAS] Add support for LAReg with identical source and destination register operands.
Summary: In this case, we're supposed to load the immediate in AT and then ADDu it with the source register and put it in the destination register. Reviewers: dsanders Reviewed By: dsanders Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D9367 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@240278 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
114489ab24
commit
8204fb27ac
@ -1774,6 +1774,16 @@ bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
|
|||||||
|
|
||||||
MCInst tmpInst;
|
MCInst tmpInst;
|
||||||
|
|
||||||
|
unsigned TmpReg = DstReg;
|
||||||
|
if (UseSrcReg && (DstReg == SrcReg)) {
|
||||||
|
// At this point we need AT to perform the expansions and we exit if it is
|
||||||
|
// not available.
|
||||||
|
unsigned ATReg = getATReg(IDLoc);
|
||||||
|
if (!ATReg)
|
||||||
|
return true;
|
||||||
|
TmpReg = ATReg;
|
||||||
|
}
|
||||||
|
|
||||||
tmpInst.setLoc(IDLoc);
|
tmpInst.setLoc(IDLoc);
|
||||||
// FIXME: gas has a special case for values that are 000...1111, which
|
// FIXME: gas has a special case for values that are 000...1111, which
|
||||||
// becomes a li -1 and then a dsrl
|
// becomes a li -1 and then a dsrl
|
||||||
@ -1810,23 +1820,23 @@ bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
|
|||||||
// For DLI, expand to an ORi instead of a LUi to avoid sign-extending the
|
// For DLI, expand to an ORi instead of a LUi to avoid sign-extending the
|
||||||
// upper 32 bits.
|
// upper 32 bits.
|
||||||
tmpInst.setOpcode(Mips::ORi);
|
tmpInst.setOpcode(Mips::ORi);
|
||||||
tmpInst.addOperand(MCOperand::createReg(DstReg));
|
tmpInst.addOperand(MCOperand::createReg(TmpReg));
|
||||||
tmpInst.addOperand(MCOperand::createReg(Mips::ZERO));
|
tmpInst.addOperand(MCOperand::createReg(Mips::ZERO));
|
||||||
tmpInst.addOperand(MCOperand::createImm(Bits31To16));
|
tmpInst.addOperand(MCOperand::createImm(Bits31To16));
|
||||||
tmpInst.setLoc(IDLoc);
|
tmpInst.setLoc(IDLoc);
|
||||||
Instructions.push_back(tmpInst);
|
Instructions.push_back(tmpInst);
|
||||||
// Move the value to the upper 16 bits by doing a 16-bit left shift.
|
// Move the value to the upper 16 bits by doing a 16-bit left shift.
|
||||||
createLShiftOri<16>(0, DstReg, IDLoc, Instructions);
|
createLShiftOri<16>(0, TmpReg, IDLoc, Instructions);
|
||||||
} else {
|
} else {
|
||||||
tmpInst.setOpcode(Mips::LUi);
|
tmpInst.setOpcode(Mips::LUi);
|
||||||
tmpInst.addOperand(MCOperand::createReg(DstReg));
|
tmpInst.addOperand(MCOperand::createReg(TmpReg));
|
||||||
tmpInst.addOperand(MCOperand::createImm(Bits31To16));
|
tmpInst.addOperand(MCOperand::createImm(Bits31To16));
|
||||||
Instructions.push_back(tmpInst);
|
Instructions.push_back(tmpInst);
|
||||||
}
|
}
|
||||||
createLShiftOri<0>(Bits15To0, DstReg, IDLoc, Instructions);
|
createLShiftOri<0>(Bits15To0, TmpReg, IDLoc, Instructions);
|
||||||
|
|
||||||
if (UseSrcReg)
|
if (UseSrcReg)
|
||||||
createAddu(DstReg, DstReg, SrcReg, Instructions);
|
createAddu(DstReg, TmpReg, SrcReg, Instructions);
|
||||||
|
|
||||||
} else if ((ImmValue & (0xffffLL << 48)) == 0) {
|
} else if ((ImmValue & (0xffffLL << 48)) == 0) {
|
||||||
if (Is32BitImm) {
|
if (Is32BitImm) {
|
||||||
@ -1853,14 +1863,14 @@ bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
|
|||||||
uint16_t Bits15To0 = ImmValue & 0xffff;
|
uint16_t Bits15To0 = ImmValue & 0xffff;
|
||||||
|
|
||||||
tmpInst.setOpcode(Mips::LUi);
|
tmpInst.setOpcode(Mips::LUi);
|
||||||
tmpInst.addOperand(MCOperand::createReg(DstReg));
|
tmpInst.addOperand(MCOperand::createReg(TmpReg));
|
||||||
tmpInst.addOperand(MCOperand::createImm(Bits47To32));
|
tmpInst.addOperand(MCOperand::createImm(Bits47To32));
|
||||||
Instructions.push_back(tmpInst);
|
Instructions.push_back(tmpInst);
|
||||||
createLShiftOri<0>(Bits31To16, DstReg, IDLoc, Instructions);
|
createLShiftOri<0>(Bits31To16, TmpReg, IDLoc, Instructions);
|
||||||
createLShiftOri<16>(Bits15To0, DstReg, IDLoc, Instructions);
|
createLShiftOri<16>(Bits15To0, TmpReg, IDLoc, Instructions);
|
||||||
|
|
||||||
if (UseSrcReg)
|
if (UseSrcReg)
|
||||||
createAddu(DstReg, DstReg, SrcReg, Instructions);
|
createAddu(DstReg, TmpReg, SrcReg, Instructions);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (Is32BitImm) {
|
if (Is32BitImm) {
|
||||||
@ -1889,22 +1899,22 @@ bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
|
|||||||
uint16_t Bits15To0 = ImmValue & 0xffff;
|
uint16_t Bits15To0 = ImmValue & 0xffff;
|
||||||
|
|
||||||
tmpInst.setOpcode(Mips::LUi);
|
tmpInst.setOpcode(Mips::LUi);
|
||||||
tmpInst.addOperand(MCOperand::createReg(DstReg));
|
tmpInst.addOperand(MCOperand::createReg(TmpReg));
|
||||||
tmpInst.addOperand(MCOperand::createImm(Bits63To48));
|
tmpInst.addOperand(MCOperand::createImm(Bits63To48));
|
||||||
Instructions.push_back(tmpInst);
|
Instructions.push_back(tmpInst);
|
||||||
createLShiftOri<0>(Bits47To32, DstReg, IDLoc, Instructions);
|
createLShiftOri<0>(Bits47To32, TmpReg, IDLoc, Instructions);
|
||||||
|
|
||||||
// When Bits31To16 is 0, do a left shift of 32 bits instead of doing
|
// When Bits31To16 is 0, do a left shift of 32 bits instead of doing
|
||||||
// two left shifts of 16 bits.
|
// two left shifts of 16 bits.
|
||||||
if (Bits31To16 == 0) {
|
if (Bits31To16 == 0) {
|
||||||
createLShiftOri<32>(Bits15To0, DstReg, IDLoc, Instructions);
|
createLShiftOri<32>(Bits15To0, TmpReg, IDLoc, Instructions);
|
||||||
} else {
|
} else {
|
||||||
createLShiftOri<16>(Bits31To16, DstReg, IDLoc, Instructions);
|
createLShiftOri<16>(Bits31To16, TmpReg, IDLoc, Instructions);
|
||||||
createLShiftOri<16>(Bits15To0, DstReg, IDLoc, Instructions);
|
createLShiftOri<16>(Bits15To0, TmpReg, IDLoc, Instructions);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UseSrcReg)
|
if (UseSrcReg)
|
||||||
createAddu(DstReg, DstReg, SrcReg, Instructions);
|
createAddu(DstReg, TmpReg, SrcReg, Instructions);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -54,6 +54,12 @@
|
|||||||
# CHECK: # fixup A - offset: 0, value: symbol@ABS_HI, kind: fixup_Mips_HI16
|
# CHECK: # fixup A - offset: 0, value: symbol@ABS_HI, kind: fixup_Mips_HI16
|
||||||
# CHECK: ori $1, $1, %lo(symbol) # encoding: [A,A,0x21,0x34]
|
# CHECK: ori $1, $1, %lo(symbol) # encoding: [A,A,0x21,0x34]
|
||||||
# CHECK: # fixup A - offset: 0, value: symbol@ABS_LO, kind: fixup_Mips_LO16
|
# CHECK: # fixup A - offset: 0, value: symbol@ABS_LO, kind: fixup_Mips_LO16
|
||||||
|
# CHECK: addu $8, $1, $8 # encoding: [0x21,0x40,0x28,0x00]
|
||||||
|
la $8, 20($8)
|
||||||
|
# CHECK: ori $8, $8, 20 # encoding: [0x14,0x00,0x08,0x35]
|
||||||
|
la $8, 65538($8)
|
||||||
|
# CHECK: lui $1, 1 # encoding: [0x01,0x00,0x01,0x3c]
|
||||||
|
# CHECK: ori $1, $1, 2 # encoding: [0x02,0x00,0x21,0x34]
|
||||||
# CHECK: addu $8, $1, $8 # encoding: [0x21,0x40,0x28,0x00]
|
# CHECK: addu $8, $1, $8 # encoding: [0x21,0x40,0x28,0x00]
|
||||||
|
|
||||||
# LW/SW and LDC1/SDC1 of symbol address, done by MipsAsmParser::expandMemInst():
|
# LW/SW and LDC1/SDC1 of symbol address, done by MipsAsmParser::expandMemInst():
|
||||||
|
Loading…
Reference in New Issue
Block a user