mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-06 01:24:35 +00:00
Add binary encoding support for multiply instructions. Some blanks left to fill in, but the basics are there.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@58626 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -82,7 +82,7 @@ namespace {
|
|||||||
const TargetInstrDesc &TID,
|
const TargetInstrDesc &TID,
|
||||||
const MachineOperand &MO);
|
const MachineOperand &MO);
|
||||||
|
|
||||||
unsigned getAddrMode1SBit(const MachineInstr &MI,
|
unsigned getAddrModeSBit(const MachineInstr &MI,
|
||||||
const TargetInstrDesc &TID) const;
|
const TargetInstrDesc &TID) const;
|
||||||
|
|
||||||
unsigned getAddrMode1InstrBinary(const MachineInstr &MI,
|
unsigned getAddrMode1InstrBinary(const MachineInstr &MI,
|
||||||
@ -97,6 +97,9 @@ namespace {
|
|||||||
unsigned getAddrMode4InstrBinary(const MachineInstr &MI,
|
unsigned getAddrMode4InstrBinary(const MachineInstr &MI,
|
||||||
const TargetInstrDesc &TID,
|
const TargetInstrDesc &TID,
|
||||||
unsigned Binary);
|
unsigned Binary);
|
||||||
|
unsigned getAddrMode6InstrBinary(const MachineInstr &MI,
|
||||||
|
const TargetInstrDesc &TID,
|
||||||
|
unsigned Binary);
|
||||||
|
|
||||||
/// getInstrBinary - Return binary encoding for the specified
|
/// getInstrBinary - Return binary encoding for the specified
|
||||||
/// machine instruction.
|
/// machine instruction.
|
||||||
@ -432,7 +435,7 @@ unsigned ARMCodeEmitter::getMachineSoImmOpValue(const MachineInstr &MI,
|
|||||||
return Binary;
|
return Binary;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned ARMCodeEmitter::getAddrMode1SBit(const MachineInstr &MI,
|
unsigned ARMCodeEmitter::getAddrModeSBit(const MachineInstr &MI,
|
||||||
const TargetInstrDesc &TID) const {
|
const TargetInstrDesc &TID) const {
|
||||||
for (unsigned i = MI.getNumOperands(), e = TID.getNumOperands(); i != e; --i){
|
for (unsigned i = MI.getNumOperands(), e = TID.getNumOperands(); i != e; --i){
|
||||||
const MachineOperand &MO = MI.getOperand(i-1);
|
const MachineOperand &MO = MI.getOperand(i-1);
|
||||||
@ -449,7 +452,7 @@ unsigned ARMCodeEmitter::getAddrMode1InstrBinary(const MachineInstr &MI,
|
|||||||
Binary |= II->getPredicate(&MI) << 28;
|
Binary |= II->getPredicate(&MI) << 28;
|
||||||
|
|
||||||
// Encode S bit if MI modifies CPSR.
|
// Encode S bit if MI modifies CPSR.
|
||||||
Binary |= getAddrMode1SBit(MI, TID);
|
Binary |= getAddrModeSBit(MI, TID);
|
||||||
|
|
||||||
// Encode register def if there is one.
|
// Encode register def if there is one.
|
||||||
unsigned NumDefs = TID.getNumDefs();
|
unsigned NumDefs = TID.getNumDefs();
|
||||||
@ -618,6 +621,33 @@ unsigned ARMCodeEmitter::getAddrMode4InstrBinary(const MachineInstr &MI,
|
|||||||
return Binary;
|
return Binary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned ARMCodeEmitter::getAddrMode6InstrBinary(const MachineInstr &MI,
|
||||||
|
const TargetInstrDesc &TID,
|
||||||
|
unsigned Binary) {
|
||||||
|
// Set the conditional execution predicate
|
||||||
|
Binary |= II->getPredicate(&MI) << 28;
|
||||||
|
|
||||||
|
// Encode S bit if MI modifies CPSR.
|
||||||
|
Binary |= getAddrModeSBit(MI, TID);
|
||||||
|
|
||||||
|
// 32x32->64bit operations have two destination registers. The number
|
||||||
|
// of register definitions will tell us if that's what we're dealing with.
|
||||||
|
int OpIdx = 0;
|
||||||
|
if (TID.getNumDefs() == 2)
|
||||||
|
Binary |= getMachineOpValue (MI, OpIdx++) << ARMII::RegRdLoShift;
|
||||||
|
|
||||||
|
// Encode Rd
|
||||||
|
Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRdHiShift;
|
||||||
|
|
||||||
|
// Encode Rm
|
||||||
|
Binary |= getMachineOpValue(MI, OpIdx++);
|
||||||
|
|
||||||
|
// Encode Rs
|
||||||
|
Binary |= getMachineOpValue(MI, OpIdx++) << ARMII::RegRsShift;
|
||||||
|
|
||||||
|
return Binary;
|
||||||
|
}
|
||||||
|
|
||||||
/// getInstrBinary - Return binary encoding for the specified
|
/// getInstrBinary - Return binary encoding for the specified
|
||||||
/// machine instruction.
|
/// machine instruction.
|
||||||
unsigned ARMCodeEmitter::getInstrBinary(const MachineInstr &MI) {
|
unsigned ARMCodeEmitter::getInstrBinary(const MachineInstr &MI) {
|
||||||
@ -636,6 +666,8 @@ unsigned ARMCodeEmitter::getInstrBinary(const MachineInstr &MI) {
|
|||||||
return getAddrMode3InstrBinary(MI, TID, Binary);
|
return getAddrMode3InstrBinary(MI, TID, Binary);
|
||||||
case ARMII::AddrMode4:
|
case ARMII::AddrMode4:
|
||||||
return getAddrMode4InstrBinary(MI, TID, Binary);
|
return getAddrMode4InstrBinary(MI, TID, Binary);
|
||||||
|
case ARMII::AddrMode6:
|
||||||
|
return getAddrMode6InstrBinary(MI, TID, Binary);
|
||||||
}
|
}
|
||||||
|
|
||||||
abort();
|
abort();
|
||||||
|
@ -659,6 +659,28 @@ class AXI4st<bits<4> opcod, dag oops, dag iops, Format f, string asm,
|
|||||||
let Inst{27-25} = 0b100;
|
let Inst{27-25} = 0b100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// addrmode6
|
||||||
|
// Unsigned multiply, multiply-accumulate instructions.
|
||||||
|
class AI6<bits<4> opcod, dag oops, dag iops, Format f, string opc,
|
||||||
|
string asm, list<dag> pattern>
|
||||||
|
: I<opcod, oops, iops, AddrMode6, Size4Bytes, IndexModeNone, f, 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;
|
||||||
|
}
|
||||||
|
class AsI6<bits<4> opcod, dag oops, dag iops, Format f, string opc,
|
||||||
|
string asm, list<dag> pattern>
|
||||||
|
: sI<opcod, oops, iops, AddrMode6, Size4Bytes, IndexModeNone, f, 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;
|
||||||
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
@ -30,8 +30,7 @@ namespace ARMII {
|
|||||||
// Instruction Flags.
|
// Instruction Flags.
|
||||||
|
|
||||||
//===------------------------------------------------------------------===//
|
//===------------------------------------------------------------------===//
|
||||||
// This three-bit field describes the addressing mode used. Zero is unused
|
// This four-bit field describes the addressing mode used.
|
||||||
// so that we can tell if we forgot to set a value.
|
|
||||||
|
|
||||||
AddrModeMask = 0xf,
|
AddrModeMask = 0xf,
|
||||||
AddrModeNone = 0,
|
AddrModeNone = 0,
|
||||||
@ -40,10 +39,11 @@ namespace ARMII {
|
|||||||
AddrMode3 = 3,
|
AddrMode3 = 3,
|
||||||
AddrMode4 = 4,
|
AddrMode4 = 4,
|
||||||
AddrMode5 = 5,
|
AddrMode5 = 5,
|
||||||
AddrModeT1 = 6,
|
AddrMode6 = 6,
|
||||||
AddrModeT2 = 7,
|
AddrModeT1 = 7,
|
||||||
AddrModeT4 = 8,
|
AddrModeT2 = 8,
|
||||||
AddrModeTs = 9, // i8 * 4 for pc and sp relative data
|
AddrModeT4 = 9,
|
||||||
|
AddrModeTs = 10, // i8 * 4 for pc and sp relative data
|
||||||
|
|
||||||
// Size* - Flags to keep track of the size of an instruction.
|
// Size* - Flags to keep track of the size of an instruction.
|
||||||
SizeShift = 4,
|
SizeShift = 4,
|
||||||
@ -117,7 +117,9 @@ namespace ARMII {
|
|||||||
// machine instructions.
|
// machine instructions.
|
||||||
RotImmShift = 8,
|
RotImmShift = 8,
|
||||||
RegRsShift = 8,
|
RegRsShift = 8,
|
||||||
|
RegRdLoShift = 12,
|
||||||
RegRdShift = 12,
|
RegRdShift = 12,
|
||||||
|
RegRdHiShift = 16,
|
||||||
RegRnShift = 16,
|
RegRnShift = 16,
|
||||||
L_BitShift = 20,
|
L_BitShift = 20,
|
||||||
S_BitShift = 20,
|
S_BitShift = 20,
|
||||||
|
@ -310,10 +310,11 @@ def AddrMode2 : AddrMode<2>;
|
|||||||
def AddrMode3 : AddrMode<3>;
|
def AddrMode3 : AddrMode<3>;
|
||||||
def AddrMode4 : AddrMode<4>;
|
def AddrMode4 : AddrMode<4>;
|
||||||
def AddrMode5 : AddrMode<5>;
|
def AddrMode5 : AddrMode<5>;
|
||||||
def AddrModeT1 : AddrMode<6>;
|
def AddrMode6 : AddrMode<6>;
|
||||||
def AddrModeT2 : AddrMode<7>;
|
def AddrModeT1 : AddrMode<7>;
|
||||||
def AddrModeT4 : AddrMode<8>;
|
def AddrModeT2 : AddrMode<8>;
|
||||||
def AddrModeTs : AddrMode<9>;
|
def AddrModeT4 : AddrMode<9>;
|
||||||
|
def AddrModeTs : AddrMode<10>;
|
||||||
|
|
||||||
// Instruction size.
|
// Instruction size.
|
||||||
class SizeFlagVal<bits<3> val> {
|
class SizeFlagVal<bits<3> val> {
|
||||||
@ -910,49 +911,53 @@ def : ARMPat<(and GPR:$src, so_imm_not:$imm),
|
|||||||
// Multiply Instructions.
|
// Multiply Instructions.
|
||||||
//
|
//
|
||||||
|
|
||||||
def MUL : AsI<0x0, (outs GPR:$dst), (ins GPR:$a, GPR:$b), MulFrm,
|
def MUL : AsI6<0b0000, (outs GPR:$dst), (ins GPR:$a, GPR:$b), MulFrm,
|
||||||
"mul", " $dst, $a, $b",
|
"mul", " $dst, $a, $b",
|
||||||
[(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
|
[(set GPR:$dst, (mul GPR:$a, GPR:$b))]>;
|
||||||
|
|
||||||
def MLA : AsI<0x2, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
|
def MLA : AsI6<0b0010, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c),
|
||||||
MulFrm, "mla", " $dst, $a, $b, $c",
|
MulFrm, "mla", " $dst, $a, $b, $c",
|
||||||
[(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
|
[(set GPR:$dst, (add (mul GPR:$a, GPR:$b), GPR:$c))]>;
|
||||||
|
|
||||||
// Extra precision multiplies with low / high results
|
// Extra precision multiplies with low / high results
|
||||||
def SMULL : AsI<0xC, (outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b),
|
def SMULL : AsI6<0b1100, (outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b),
|
||||||
MulFrm, "smull", " $ldst, $hdst, $a, $b", []>;
|
MulFrm, "smull", " $ldst, $hdst, $a, $b", []>;
|
||||||
|
|
||||||
def UMULL : AsI<0x8, (outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b),
|
def UMULL : AsI6<0b1000, (outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b),
|
||||||
MulFrm, "umull", " $ldst, $hdst, $a, $b", []>;
|
MulFrm, "umull", " $ldst, $hdst, $a, $b", []>;
|
||||||
|
|
||||||
// Multiply + accumulate
|
// Multiply + accumulate
|
||||||
def SMLAL : AsI<0xE, (outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b),
|
def SMLAL : AsI6<0b1110, (outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b),
|
||||||
MulFrm, "smlal", " $ldst, $hdst, $a, $b", []>;
|
MulFrm, "smlal", " $ldst, $hdst, $a, $b", []>;
|
||||||
|
|
||||||
def UMLAL : AsI<0xA, (outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b),
|
def UMLAL : AsI6<0b1010, (outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b),
|
||||||
MulFrm, "umlal", " $ldst, $hdst, $a, $b", []>;
|
MulFrm, "umlal", " $ldst, $hdst, $a, $b", []>;
|
||||||
|
|
||||||
def UMAAL : AI<0x0, (outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b), MulFrm,
|
def UMAAL : AI6 <0b0000, (outs GPR:$ldst, GPR:$hdst), (ins GPR:$a, GPR:$b),
|
||||||
"umaal", " $ldst, $hdst, $a, $b", []>,
|
MulFrm, "umaal", " $ldst, $hdst, $a, $b", []>,
|
||||||
Requires<[IsARM, HasV6]>;
|
Requires<[IsARM, HasV6]>;
|
||||||
|
|
||||||
// Most significant word multiply
|
// Most significant word multiply
|
||||||
|
// FIXME: encoding
|
||||||
def SMMUL : AI<0x0, (outs GPR:$dst), (ins GPR:$a, GPR:$b), MulFrm,
|
def SMMUL : AI<0x0, (outs GPR:$dst), (ins GPR:$a, GPR:$b), MulFrm,
|
||||||
"smmul", " $dst, $a, $b",
|
"smmul", " $dst, $a, $b",
|
||||||
[(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>,
|
[(set GPR:$dst, (mulhs GPR:$a, GPR:$b))]>,
|
||||||
Requires<[IsARM, HasV6]>;
|
Requires<[IsARM, HasV6]>;
|
||||||
|
|
||||||
|
// FIXME: encoding
|
||||||
def SMMLA : AI<0x0, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), MulFrm,
|
def SMMLA : AI<0x0, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), MulFrm,
|
||||||
"smmla", " $dst, $a, $b, $c",
|
"smmla", " $dst, $a, $b, $c",
|
||||||
[(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>,
|
[(set GPR:$dst, (add (mulhs GPR:$a, GPR:$b), GPR:$c))]>,
|
||||||
Requires<[IsARM, HasV6]>;
|
Requires<[IsARM, HasV6]>;
|
||||||
|
|
||||||
|
|
||||||
|
// FIXME: encoding
|
||||||
def SMMLS : AI<0x0, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), MulFrm,
|
def SMMLS : AI<0x0, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$c), MulFrm,
|
||||||
"smmls", " $dst, $a, $b, $c",
|
"smmls", " $dst, $a, $b, $c",
|
||||||
[(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>,
|
[(set GPR:$dst, (sub GPR:$c, (mulhs GPR:$a, GPR:$b)))]>,
|
||||||
Requires<[IsARM, HasV6]>;
|
Requires<[IsARM, HasV6]>;
|
||||||
|
|
||||||
|
// FIXME: encoding
|
||||||
multiclass AI_smul<string opc, PatFrag opnode> {
|
multiclass AI_smul<string opc, PatFrag opnode> {
|
||||||
def BB : AI<0x8, (outs GPR:$dst), (ins GPR:$a, GPR:$b), MulSMUL,
|
def BB : AI<0x8, (outs GPR:$dst), (ins GPR:$a, GPR:$b), MulSMUL,
|
||||||
!strconcat(opc, "bb"), " $dst, $a, $b",
|
!strconcat(opc, "bb"), " $dst, $a, $b",
|
||||||
@ -992,6 +997,7 @@ multiclass AI_smul<string opc, PatFrag opnode> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// FIXME: encoding
|
||||||
multiclass AI_smla<string opc, PatFrag opnode> {
|
multiclass AI_smla<string opc, PatFrag opnode> {
|
||||||
def BB : AI<0x8, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), MulSMLA,
|
def BB : AI<0x8, (outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc), MulSMLA,
|
||||||
!strconcat(opc, "bb"), " $dst, $a, $b, $acc",
|
!strconcat(opc, "bb"), " $dst, $a, $b, $acc",
|
||||||
@ -1031,7 +1037,9 @@ multiclass AI_smla<string opc, PatFrag opnode> {
|
|||||||
Requires<[IsARM, HasV5TE]>;
|
Requires<[IsARM, HasV5TE]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: encoding
|
||||||
defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
|
defm SMUL : AI_smul<"smul", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
|
||||||
|
// FIXME: encoding
|
||||||
defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
|
defm SMLA : AI_smla<"smla", BinOpFrag<(mul node:$LHS, node:$RHS)>>;
|
||||||
|
|
||||||
// TODO: Halfword multiple accumulate long: SMLAL<x><y>
|
// TODO: Halfword multiple accumulate long: SMLAL<x><y>
|
||||||
|
Reference in New Issue
Block a user