diff options
author | Evan Cheng <evan.cheng@apple.com> | 2008-11-06 01:21:28 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2008-11-06 01:21:28 +0000 |
commit | fbc9d412efdfa1ed30ff4d2baedc775a5f59c638 (patch) | |
tree | fa07bbf3a49792045572d0f43d087b7ee916d7b7 /lib/Target/ARM | |
parent | 6863fb033a9079e04edc7a568e34098bcf5b9ebe (diff) | |
download | external_llvm-fbc9d412efdfa1ed30ff4d2baedc775a5f59c638.zip external_llvm-fbc9d412efdfa1ed30ff4d2baedc775a5f59c638.tar.gz external_llvm-fbc9d412efdfa1ed30ff4d2baedc775a5f59c638.tar.bz2 |
Fix encoding of multiple instructions with 3 src operands; also handle smmul, smmla, and smmls.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@58789 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM')
-rw-r--r-- | lib/Target/ARM/ARMCodeEmitter.cpp | 13 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrFormats.td | 70 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrInfo.h | 37 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrInfo.td | 53 |
4 files changed, 96 insertions, 77 deletions
diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp index ce62c59..945a259 100644 --- a/lib/Target/ARM/ARMCodeEmitter.cpp +++ b/lib/Target/ARM/ARMCodeEmitter.cpp @@ -96,7 +96,7 @@ namespace { void emitLoadStoreMultipleInstruction(const MachineInstr &MI); - void emitMulFrm1Instruction(const MachineInstr &MI); + void emitMulFrmInstruction(const MachineInstr &MI); void emitBranchInstruction(const MachineInstr &MI); @@ -285,8 +285,8 @@ void ARMCodeEmitter::emitInstruction(const MachineInstr &MI) { case ARMII::StMulFrm: emitLoadStoreMultipleInstruction(MI); break; - case ARMII::MulFrm1: - emitMulFrm1Instruction(MI); + case ARMII::MulFrm: + emitMulFrmInstruction(MI); break; case ARMII::Branch: emitBranchInstruction(MI); @@ -675,7 +675,7 @@ void ARMCodeEmitter::emitLoadStoreMultipleInstruction(const MachineInstr &MI) { emitWordLE(Binary); } -void ARMCodeEmitter::emitMulFrm1Instruction(const MachineInstr &MI) { +void ARMCodeEmitter::emitMulFrmInstruction(const MachineInstr &MI) { const TargetInstrDesc &TID = MI.getDesc(); // Part of binary is determined by TableGn. @@ -702,6 +702,11 @@ void ARMCodeEmitter::emitMulFrm1Instruction(const MachineInstr &MI) { // Encode Rs Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRsShift; + // Many multiple instructions (e.g. MLA) have three src operands. Encode + // it as Rn (for multiply, that's in the same offset as RdLo. + if (TID.getNumOperands() - TID.getNumDefs() == 3) + Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRdLoShift; + emitWordLE(Binary); } diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td index 9df7e6f..3ac9b1e 100644 --- a/lib/Target/ARM/ARMInstrFormats.td +++ b/lib/Target/ARM/ARMInstrFormats.td @@ -20,28 +20,27 @@ class Format<bits<5> val> { } def Pseudo : Format<1>; -def MulFrm1 : Format<2>; -def MulFrm2 : Format<3>; -def MulSMLAW : Format<4>; -def MulSMULW : Format<5>; -def MulSMLA : Format<6>; -def MulSMUL : Format<7>; -def Branch : Format<8>; -def BranchMisc : Format<9>; - -def DPFrm : Format<10>; -def DPSoRegFrm : Format<11>; - -def LdFrm : Format<12>; -def StFrm : Format<13>; -def LdMiscFrm : Format<14>; -def StMiscFrm : Format<15>; -def LdMulFrm : Format<16>; -def StMulFrm : Format<17>; - -def ArithMisc : Format<18>; -def ThumbFrm : Format<19>; -def VFPFrm : Format<20>; +def MulFrm : Format<2>; +def MulSMLAW : Format<3>; +def MulSMULW : Format<4>; +def MulSMLA : Format<5>; +def MulSMUL : Format<6>; +def Branch : Format<7>; +def BranchMisc : Format<8>; + +def DPFrm : Format<9>; +def DPSoRegFrm : Format<10>; + +def LdFrm : Format<11>; +def StFrm : Format<12>; +def LdMiscFrm : Format<13>; +def StMiscFrm : Format<14>; +def LdMulFrm : Format<15>; +def StMulFrm : Format<16>; + +def ArithMisc : Format<17>; +def ThumbFrm : Format<18>; +def VFPFrm : Format<19>; // Misc flag for data processing instructions that indicates whether // the instruction has a Rn register operand. @@ -679,23 +678,30 @@ class AXI4st<bits<4> opcod, dag oops, dag iops, Format f, string asm, } // Unsigned multiply, multiply-accumulate instructions. -class AMul1I<bits<4> opcod, dag oops, dag iops, string opc, +class AMul1I<bits<7> mulopc, dag oops, dag iops, string opc, string asm, list<dag> pattern> - : I<opcod, oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm1, opc, + : I<0, oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, opc, asm,"",pattern> { - // FIXME: bits 7-4 should be a sub-mode (for SMLAxx, SMLAWy, ...) let Inst{7-4} = 0b1001; - let Inst{27-24} = 0b0000; - let Inst{23-20} = opcod; + let Inst{20} = 0; // S bit + let Inst{27-21} = mulopc; } -class AsMul1I<bits<4> opcod, dag oops, dag iops, string opc, +class AsMul1I<bits<7> mulopc, dag oops, dag iops, string opc, string asm, list<dag> pattern> - : sI<opcod, oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm1, opc, + : sI<0, oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, opc, asm,"",pattern> { - // FIXME: bits 7-4 should be a sub-mode (for SMLAxx, SMLAWy, ...) let Inst{7-4} = 0b1001; - let Inst{27-24} = 0b0000; - let Inst{23-20} = opcod; + let Inst{27-21} = mulopc; +} + +// Most significant word multiply +class AMul2I<bits<7> mulopc, dag oops, dag iops, string opc, + string asm, list<dag> pattern> + : I<0, oops, iops, AddrModeNone, Size4Bytes, IndexModeNone, MulFrm, opc, + asm,"",pattern> { + let Inst{7-4} = 0b1001; + let Inst{20} = 1; + let Inst{27-21} = mulopc; } //===----------------------------------------------------------------------===// diff --git a/lib/Target/ARM/ARMInstrInfo.h b/lib/Target/ARM/ARMInstrInfo.h index 6f1bf38..426ed4e 100644 --- a/lib/Target/ARM/ARMInstrInfo.h +++ b/lib/Target/ARM/ARMInstrInfo.h @@ -80,37 +80,36 @@ namespace ARMII { Pseudo = 1 << FormShift, // Multiply instructions - MulFrm1 = 2 << FormShift, - MulFrm2 = 3 << FormShift, - MulSMLAW = 4 << FormShift, - MulSMULW = 5 << FormShift, - MulSMLA = 6 << FormShift, - MulSMUL = 7 << FormShift, + MulFrm = 2 << FormShift, + MulSMLAW = 3 << FormShift, + MulSMULW = 4 << FormShift, + MulSMLA = 5 << FormShift, + MulSMUL = 6 << FormShift, // Branch instructions - Branch = 8 << FormShift, - BranchMisc = 9 << FormShift, + Branch = 7 << FormShift, + BranchMisc = 8 << FormShift, // Data Processing instructions - DPFrm = 10 << FormShift, - DPSoRegFrm = 11 << FormShift, + DPFrm = 9 << FormShift, + DPSoRegFrm = 10 << FormShift, // Load and Store - LdFrm = 12 << FormShift, - StFrm = 13 << FormShift, - LdMiscFrm = 14 << FormShift, - StMiscFrm = 15 << FormShift, - LdMulFrm = 16 << FormShift, - StMulFrm = 17 << FormShift, + LdFrm = 11 << FormShift, + StFrm = 12 << FormShift, + LdMiscFrm = 13 << FormShift, + StMiscFrm = 14 << FormShift, + LdMulFrm = 15 << FormShift, + StMulFrm = 16 << FormShift, // Miscellaneous arithmetic instructions - ArithMisc = 18 << FormShift, + ArithMisc = 17 << FormShift, // Thumb format - ThumbFrm = 19 << FormShift, + ThumbFrm = 18 << FormShift, // VFP format - VPFFrm = 20 << FormShift, + VPFFrm = 19 << FormShift, //===------------------------------------------------------------------===// // Field shifts - such shifts are used to set field while generating diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index fbeaa51..e57b5d9 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -905,51 +905,60 @@ def : ARMPat<(and GPR:$src, so_imm_not:$imm), // Multiply Instructions. // -def MUL : AsMul1I<0b0000, (outs GPR:$dst), (ins GPR:$a, GPR:$b), +def MUL : AsMul1I<0b0000000, (outs GPR:$dst), (ins GPR:$a, GPR:$b), "mul", " $dst, $a, $b", [(set GPR:$dst, (mul GPR:$a, GPR:$b))]>; -def MLA : AsMul1I<0b0010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), +def MLA : AsMul1I<0b0000001, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), "mla", " $dst, $a, $b, $c", [(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>; // Extra precision multiplies with low / high results -def SMULL : AsMul1I<0b1100, (outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), - "smull", " $ldst, $hdst, $a, $b", []>; +def SMULL : AsMul1I<0b0000110, (outs GPR:$ldst, GPR:$hdst), + (ins GPR:$a, GPR:$b), + "smull", " $ldst, $hdst, $a, $b", []>; -def UMULL : AsMul1I<0b1000, (outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), - "umull", " $ldst, $hdst, $a, $b", []>; +def UMULL : AsMul1I<0b0000100, (outs GPR:$ldst, GPR:$hdst), + (ins GPR:$a, GPR:$b), + "umull", " $ldst, $hdst, $a, $b", []>; // Multiply + accumulate -def SMLAL : AsMul1I<0b1110, (outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), - "smlal", " $ldst, $hdst, $a, $b", []>; +def SMLAL : AsMul1I<0b0000111, (outs GPR:$ldst, GPR:$hdst), + (ins GPR:$a, GPR:$b), + "smlal", " $ldst, $hdst, $a, $b", []>; -def UMLAL : AsMul1I<0b1010, (outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), - "umlal", " $ldst, $hdst, $a, $b", []>; +def UMLAL : AsMul1I<0b0000101, (outs GPR:$ldst, GPR:$hdst), + (ins GPR:$a, GPR:$b), + "umlal", " $ldst, $hdst, $a, $b", []>; -def UMAAL : AMul1I<0b0000, (outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), - "umaal", " $ldst, $hdst, $a, $b", []>, - Requires<[IsARM, HasV6]>; +def UMAAL : AMul1I <0b0000010, (outs GPR:$ldst, GPR:$hdst), + (ins GPR:$a, GPR:$b), + "umaal", " $ldst, $hdst, $a, $b", []>, + Requires<[IsARM, HasV6]>; // Most significant word multiply -// FIXME: encoding -def SMMUL : AI<0x0, (outs GPR:$dst), (ins GPR:$a, GPR:$b), MulFrm2, +def SMMUL : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b), "smmul", " $dst, $a, $b", [(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>, - Requires<[IsARM, HasV6]>; + Requires<[IsARM, HasV6]> { + let Inst{7-4} = 0b0001; + let Inst{15-12} = 0b1111; +} -// FIXME: encoding -def SMMLA : AI<0x0, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), MulFrm2, +def SMMLA : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), "smmla", " $dst, $a, $b, $c", [(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>, - Requires<[IsARM, HasV6]>; + Requires<[IsARM, HasV6]> { + let Inst{7-4} = 0b0001; +} -// FIXME: encoding -def SMMLS : AI<0x0, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), MulFrm2, +def SMMLS : AMul2I <0b0111010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), "smmls", " $dst, $a, $b, $c", [(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>, - Requires<[IsARM, HasV6]>; + Requires<[IsARM, HasV6]> { + let Inst{7-4} = 0b1101; +} // FIXME: encoding multiclass AI_smul<string opc, PatFrag opnode> { |