diff options
Diffstat (limited to 'lib/Target')
-rw-r--r-- | lib/Target/ARM/ARMInstrInfo.td | 10 | ||||
-rw-r--r-- | lib/Target/ARM/ARMMul.cpp | 14 | ||||
-rw-r--r-- | lib/Target/ARM/README.txt | 5 |
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. + +---------------------------------------------------------- |