aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/Mips/MipsAsmPrinter.cpp36
-rw-r--r--test/CodeGen/Mips/inlineasm-operand-code.ll12
2 files changed, 33 insertions, 15 deletions
diff --git a/lib/Target/Mips/MipsAsmPrinter.cpp b/lib/Target/Mips/MipsAsmPrinter.cpp
index fc47ba5bfd..3c50bae071 100644
--- a/lib/Target/Mips/MipsAsmPrinter.cpp
+++ b/lib/Target/Mips/MipsAsmPrinter.cpp
@@ -333,8 +333,9 @@ bool MipsAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
O << "$0";
return false;
}
- case 'D': {
- // Second part of a double word register operand
+ case 'D': // Second part of a double word register operand
+ case 'L': // Low order register of a double word register operand
+ {
if (OpNum == 0)
return true;
const MachineOperand &FlagsOP = MI->getOperand(OpNum - 1);
@@ -353,19 +354,26 @@ bool MipsAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
return true;
}
unsigned RegOp;
- switch(ExtraCode[0]) {
- case 'D':
- RegOp = (!Subtarget->isGP32bit()) ? OpNum : OpNum + 1;
- break;
+ if (Subtarget->isGP64bit())
+ RegOp = OpNum;
+ else {
+ // Endianess reverses which register holds the high or low value
+ switch(ExtraCode[0]) {
+ case 'D':
+ RegOp = (Subtarget->isLittle()) ? OpNum : OpNum+1;
+ break;
+ case 'L':
+ RegOp = (Subtarget->isLittle()) ? OpNum+1 : OpNum;
+ }
+ if (RegOp >= MI->getNumOperands())
+ return true;
+ const MachineOperand &MO = MI->getOperand(RegOp);
+ if (!MO.isReg())
+ return true;
+ unsigned Reg = MO.getReg();
+ O << '$' << MipsInstPrinter::getRegisterName(Reg);
+ return false;
}
- if (RegOp >= MI->getNumOperands())
- return true;
- const MachineOperand &MO = MI->getOperand(RegOp);
- if (!MO.isReg())
- return true;
- unsigned Reg = MO.getReg();
- O << '$' << MipsInstPrinter::getRegisterName(Reg);
- return false;
}
}
}
diff --git a/test/CodeGen/Mips/inlineasm-operand-code.ll b/test/CodeGen/Mips/inlineasm-operand-code.ll
index 8398cb0e38..97ec629db2 100644
--- a/test/CodeGen/Mips/inlineasm-operand-code.ll
+++ b/test/CodeGen/Mips/inlineasm-operand-code.ll
@@ -56,7 +56,7 @@ entry:
;LITTLE: lw $[[SECOND:[0-9]+]], 4(${{[0-9]+}})
;LITTLE-NEXT: lw $[[FIRST:[0-9]+]], 0(${{[0-9]+}})
;LITTLE: #APP
-;LITTLE: or ${{[0-9]+}},$[[SECOND]],${{[0-9]+}}
+;LITTLE: or ${{[0-9]+}},$[[FIRST]],${{[0-9]+}}
;LITTLE: #NO_APP
; D, in big endian the source reg will also be 4 bytes into the long long
@@ -77,6 +77,16 @@ entry:
%trunc1 = trunc i64 %7 to i32
tail call i32 asm sideeffect "or $0,${1:D},$2", "=r,r,r"(i64 %7, i32 %trunc1) nounwind
+; L, in little endian the source reg will be 4 bytes into the long long
+;LITTLE: #APP
+;LITTLE: or ${{[0-9]+}},$[[SECOND]],${{[0-9]+}}
+;LITTLE: #NO_APP
+; L, in big endian the source reg will be 0 bytes into the long long
+;BIG: #APP
+;BIG: or ${{[0-9]+}},$[[FIRST]],${{[0-9]+}}
+;BIG: #NO_APP
+ tail call i32 asm sideeffect "or $0,${1:L},$2", "=r,r,r"(i64 %7, i32 %trunc1) nounwind
+
ret i32 0
}