mirror of
https://github.com/RPCSX/llvm.git
synced 2025-01-03 10:19:18 +00:00
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
This commit is contained in:
parent
6863fb033a
commit
fbc9d412ef
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 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<10>;
|
||||
def DPSoRegFrm : Format<11>;
|
||||
def DPFrm : Format<9>;
|
||||
def DPSoRegFrm : Format<10>;
|
||||
|
||||
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 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<18>;
|
||||
def ThumbFrm : Format<19>;
|
||||
def VFPFrm : Format<20>;
|
||||
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;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -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
|
||||
|
@ -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> {
|
||||
|
Loading…
Reference in New Issue
Block a user