mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-30 16:17:05 +00:00 
			
		
		
		
	implement smull and umull
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30975 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
		| @@ -174,6 +174,16 @@ def MUL     : InstARM<(ops IntRegs:$dst, IntRegs:$a, IntRegs:$b), | |||||||
|                        "mul $dst, $a, $b", |                        "mul $dst, $a, $b", | ||||||
| 		       [(set IntRegs:$dst, (mul IntRegs:$a, IntRegs:$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), | def bcond      : InstARM<(ops brtarget:$dst, CCOp:$cc), | ||||||
| 		         "b$cc $dst", | 		         "b$cc $dst", | ||||||
| 		         [(armbr bb:$dst, imm:$cc)]>; | 		         [(armbr bb:$dst, imm:$cc)]>; | ||||||
|   | |||||||
| @@ -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) { |          I != E; ++I) { | ||||||
|       MachineInstr *MI = 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 &RdOp = MI->getOperand(0); | ||||||
|         MachineOperand &RmOp = MI->getOperand(1); |         MachineOperand &RmOp = MI->getOperand(1); | ||||||
|         MachineOperand &RsOp = MI->getOperand(2); |         MachineOperand &RsOp = MI->getOperand(2); | ||||||
| @@ -48,7 +51,7 @@ bool FixMul::runOnMachineFunction(MachineFunction &MF) { | |||||||
|         unsigned Rm = RmOp.getReg(); |         unsigned Rm = RmOp.getReg(); | ||||||
|         unsigned Rs = RsOp.getReg(); |         unsigned Rs = RsOp.getReg(); | ||||||
|  |  | ||||||
|         if(Rd == Rm) { |         if (Rd == Rm) { | ||||||
|           Changed = true; |           Changed = true; | ||||||
|           if (Rd != Rs) { |           if (Rd != Rs) { | ||||||
| 	    //Rd and Rm must be distinct, but Rd can be equal to 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); |             RmOp.setReg(Rs); | ||||||
|             RsOp.setReg(Rm); |             RsOp.setReg(Rm); | ||||||
|           } else { |           } 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); |               .addImm(ARMShift::LSL); | ||||||
|             RmOp.setReg(ARM::R12); |             RmOp.setReg(scratch); | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|   | |||||||
| @@ -46,3 +46,8 @@ declare void %g(int, int, int, int, int) | |||||||
| Only needs 8 bytes of stack space. We currently allocate 16. | 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. | ||||||
|  |  | ||||||
|  | ---------------------------------------------------------- | ||||||
|   | |||||||
| @@ -7,7 +7,9 @@ | |||||||
| ; RUN: llvm-as < %s | llc -march=arm | grep "adds" | wc -l | grep 1 && | ; RUN: llvm-as < %s | llc -march=arm | grep "adds" | wc -l | grep 1 && | ||||||
| ; RUN: llvm-as < %s | llc -march=arm | grep "adcs" | wc -l | grep 1 && | ; RUN: llvm-as < %s | llc -march=arm | grep "adcs" | wc -l | grep 1 && | ||||||
| ; RUN: llvm-as < %s | llc -march=arm | grep "subs" | wc -l | grep 1 && | ; RUN: llvm-as < %s | llc -march=arm | grep "subs" | wc -l | grep 1 && | ||||||
| ; RUN: llvm-as < %s | llc -march=arm | grep "sbcs" | wc -l | grep 1 | ; RUN: llvm-as < %s | llc -march=arm | grep "sbcs" | wc -l | grep 1 && | ||||||
|  | ; RUN: llvm-as < %s | llc -march=arm | grep "smull" | wc -l | grep 1 && | ||||||
|  | ; RUN: llvm-as < %s | llc -march=arm | grep "umull" | wc -l | grep 1 | ||||||
|  |  | ||||||
| long %f1() { | long %f1() { | ||||||
| entry: | entry: | ||||||
| @@ -52,3 +54,19 @@ entry: | |||||||
| 	%tmp = sub long %a, %b | 	%tmp = sub long %a, %b | ||||||
| 	ret long %tmp | 	ret long %tmp | ||||||
| } | } | ||||||
|  |  | ||||||
|  | long %f(int %a, int %b) { | ||||||
|  | entry: | ||||||
|  | 	%tmp = cast int %a to long | ||||||
|  | 	%tmp1 = cast int %b to long | ||||||
|  | 	%tmp2 = mul long %tmp1, %tmp | ||||||
|  | 	ret long %tmp2 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | ulong %g(uint %a, uint %b) { | ||||||
|  | entry: | ||||||
|  | 	%tmp = cast uint %a to ulong | ||||||
|  | 	%tmp1 = cast uint %b to ulong | ||||||
|  | 	%tmp2 = mul ulong %tmp1, %tmp | ||||||
|  | 	ret ulong %tmp2 | ||||||
|  | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user