mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-13 06:38:44 +00:00
[mips] Fix expansion of memory operation if destination register is not a GPR.
Summary: The assembler tries to reuse the destination register for memory operations whenever it can but it's not possible to do so if the destination register is not a GPR. Example: ldc1 $f0, sym should expand to: lui $at, %hi(sym) ldc1 $f0, %lo(sym)($at) It's entirely wrong to expand to: lui $f0, %hi(sym) ldc1 $f0, %lo(sym)($f0) Reviewers: dsanders Reviewed By: dsanders Differential Revision: http://reviews.llvm.org/D4173 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@211169 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
cacc062572
commit
c39b18b306
@ -1144,10 +1144,35 @@ void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
|
||||
ExprOffset = Inst.getOperand(2).getExpr();
|
||||
// All instructions will have the same location.
|
||||
TempInst.setLoc(IDLoc);
|
||||
// 1st instruction in expansion is LUi. For load instruction we can use
|
||||
// the dst register as a temporary if base and dst are different,
|
||||
// but for stores we must use $at.
|
||||
if (isLoad && (BaseRegNum != RegOpNum))
|
||||
// These are some of the types of expansions we perform here:
|
||||
// 1) lw $8, sym => lui $8, %hi(sym)
|
||||
// lw $8, %lo(sym)($8)
|
||||
// 2) lw $8, offset($9) => lui $8, %hi(offset)
|
||||
// add $8, $8, $9
|
||||
// lw $8, %lo(offset)($9)
|
||||
// 3) lw $8, offset($8) => lui $at, %hi(offset)
|
||||
// add $at, $at, $8
|
||||
// lw $8, %lo(offset)($at)
|
||||
// 4) sw $8, sym => lui $at, %hi(sym)
|
||||
// sw $8, %lo(sym)($at)
|
||||
// 5) sw $8, offset($8) => lui $at, %hi(offset)
|
||||
// add $at, $at, $8
|
||||
// sw $8, %lo(offset)($at)
|
||||
// 6) ldc1 $f0, sym => lui $at, %hi(sym)
|
||||
// ldc1 $f0, %lo(sym)($at)
|
||||
//
|
||||
// For load instructions we can use the destination register as a temporary
|
||||
// if base and dst are different (examples 1 and 2) and if the base register
|
||||
// is general purpose otherwise we must use $at (example 6) and error if it's
|
||||
// not available. For stores we must use $at (examples 4 and 5) because we
|
||||
// must not clobber the source register setting up the offset.
|
||||
const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
|
||||
int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
|
||||
unsigned RegClassIDOp0 =
|
||||
getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
|
||||
bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
|
||||
(RegClassIDOp0 == Mips::GPR64RegClassID);
|
||||
if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
|
||||
TmpRegNum = RegOpNum;
|
||||
else {
|
||||
int AT = getATReg(IDLoc);
|
||||
|
@ -34,6 +34,11 @@
|
||||
# CHECK: addu $1, $1, $9 # encoding: [0x21,0x08,0x29,0x00]
|
||||
# CHECK: sw $10, 57920($1) # encoding: [0x40,0xe2,0x2a,0xac]
|
||||
|
||||
# CHECK: lui $1, %hi(symbol)
|
||||
# CHECK: ldc1 $f0, %lo(symbol)($1)
|
||||
# CHECK: lui $1, %hi(symbol)
|
||||
# CHECK: sdc1 $f0, %lo(symbol)($1)
|
||||
|
||||
li $5,123
|
||||
li $6,-2345
|
||||
li $7,65538
|
||||
@ -51,3 +56,6 @@
|
||||
|
||||
lw $t2, 655483($a0)
|
||||
sw $t2, 123456($t1)
|
||||
|
||||
ldc1 $f0, symbol
|
||||
sdc1 $f0, symbol
|
||||
|
Loading…
Reference in New Issue
Block a user