aboutsummaryrefslogtreecommitdiff
path: root/lib/Target
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target')
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td10
-rw-r--r--lib/Target/ARM/ARMMul.cpp14
-rw-r--r--lib/Target/ARM/README.txt5
3 files changed, 24 insertions, 5 deletions
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td
index 17e0eecf97..6582a5b264 100644
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -174,6 +174,16 @@ def MUL : InstARM<(ops IntRegs:$dst, IntRegs:$a, IntRegs:$b),
"mul $dst, $a, $b",
[(set IntRegs:$dst, (mul IntRegs:$a, IntRegs:$b))]>;
+let Defs = [R0] in {
+ def SMULL : InstARM<(ops IntRegs:$dst, IntRegs:$a, IntRegs:$b),
+ "smull r12, $dst, $a, $b",
+ [(set IntRegs:$dst, (mulhs IntRegs:$a, IntRegs:$b))]>;
+
+ def UMULL : InstARM<(ops IntRegs:$dst, IntRegs:$a, IntRegs:$b),
+ "umull r12, $dst, $a, $b",
+ [(set IntRegs:$dst, (mulhu IntRegs:$a, IntRegs:$b))]>;
+}
+
def bcond : InstARM<(ops brtarget:$dst, CCOp:$cc),
"b$cc $dst",
[(armbr bb:$dst, imm:$cc)]>;
diff --git a/lib/Target/ARM/ARMMul.cpp b/lib/Target/ARM/ARMMul.cpp
index 185fb96783..474039db27 100644
--- a/lib/Target/ARM/ARMMul.cpp
+++ b/lib/Target/ARM/ARMMul.cpp
@@ -8,7 +8,7 @@
//
//===----------------------------------------------------------------------===//
//
-// Modify the ARM multiplication instructions so that Rd and Rm are distinct
+// Modify the ARM multiplication instructions so that Rd{Hi,Lo} and Rm are distinct
//
//===----------------------------------------------------------------------===//
@@ -39,7 +39,10 @@ bool FixMul::runOnMachineFunction(MachineFunction &MF) {
I != E; ++I) {
MachineInstr *MI = I;
- if (MI->getOpcode() == ARM::MUL) {
+ int Op = MI->getOpcode();
+ if (Op == ARM::MUL ||
+ Op == ARM::SMULL ||
+ Op == ARM::UMULL) {
MachineOperand &RdOp = MI->getOperand(0);
MachineOperand &RmOp = MI->getOperand(1);
MachineOperand &RsOp = MI->getOperand(2);
@@ -48,7 +51,7 @@ bool FixMul::runOnMachineFunction(MachineFunction &MF) {
unsigned Rm = RmOp.getReg();
unsigned Rs = RsOp.getReg();
- if(Rd == Rm) {
+ if (Rd == Rm) {
Changed = true;
if (Rd != Rs) {
//Rd and Rm must be distinct, but Rd can be equal to Rs.
@@ -56,9 +59,10 @@ bool FixMul::runOnMachineFunction(MachineFunction &MF) {
RmOp.setReg(Rs);
RsOp.setReg(Rm);
} else {
- BuildMI(MBB, I, ARM::MOV, 3, ARM::R12).addReg(Rm).addImm(0)
+ unsigned scratch = Op == ARM::MUL ? ARM::R12 : ARM::R0;
+ BuildMI(MBB, I, ARM::MOV, 3, scratch).addReg(Rm).addImm(0)
.addImm(ARMShift::LSL);
- RmOp.setReg(ARM::R12);
+ RmOp.setReg(scratch);
}
}
}
diff --git a/lib/Target/ARM/README.txt b/lib/Target/ARM/README.txt
index 06a8cceda5..768a2e6f3e 100644
--- a/lib/Target/ARM/README.txt
+++ b/lib/Target/ARM/README.txt
@@ -46,3 +46,8 @@ declare void %g(int, int, int, int, int)
Only needs 8 bytes of stack space. We currently allocate 16.
----------------------------------------------------------
+
+32 x 32 -> 64 multiplications currently uses two instructions. We
+should try to declare smull and umull as returning two values.
+
+----------------------------------------------------------