Skip to content

Commit

Permalink
Add support for SPE load/store from memory.
Browse files Browse the repository at this point in the history
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@215220 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
jsonn committed Aug 8, 2014
1 parent 0bd9423 commit c9def6b
Show file tree
Hide file tree
Showing 6 changed files with 359 additions and 0 deletions.
9 changes: 9 additions & 0 deletions lib/Target/PowerPC/AsmParser/PPCAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,15 @@ struct PPCOperand : public MCParsedAsmOperand {
bool isU5Imm() const { return Kind == Immediate && isUInt<5>(getImm()); }
bool isS5Imm() const { return Kind == Immediate && isInt<5>(getImm()); }
bool isU6Imm() const { return Kind == Immediate && isUInt<6>(getImm()); }
bool isU6ImmX2() const { return Kind == Immediate &&
isUInt<6>(getImm()) &&
(getImm() & 1) == 0; }
bool isU7ImmX4() const { return Kind == Immediate &&
isUInt<7>(getImm()) &&
(getImm() & 3) == 0; }
bool isU8ImmX8() const { return Kind == Immediate &&
isUInt<8>(getImm()) &&
(getImm() & 7) == 0; }
bool isU16Imm() const { return Kind == Expression ||
(Kind == Immediate && isUInt<16>(getImm())); }
bool isS16Imm() const { return Kind == Expression ||
Expand Down
57 changes: 57 additions & 0 deletions lib/Target/PowerPC/MCTargetDesc/PPCMCCodeEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,15 @@ class PPCMCCodeEmitter : public MCCodeEmitter {
unsigned getMemRIXEncoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
unsigned getSPE8DisEncoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
unsigned getSPE4DisEncoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
unsigned getSPE2DisEncoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
unsigned getTLSRegEncoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
Expand Down Expand Up @@ -260,6 +269,54 @@ unsigned PPCMCCodeEmitter::getMemRIXEncoding(const MCInst &MI, unsigned OpNo,
}


unsigned PPCMCCodeEmitter::getSPE8DisEncoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI)
const {
// Encode (imm, reg) as a spe8dis, which has the low 5-bits of (imm / 8)
// as the displacement and the next 5 bits as the register #.
assert(MI.getOperand(OpNo+1).isReg());
uint32_t RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI) << 5;

const MCOperand &MO = MI.getOperand(OpNo);
assert(MO.isImm());
uint32_t Imm = getMachineOpValue(MI, MO, Fixups, STI) >> 3;
return reverseBits(Imm | RegBits) >> 22;
}


unsigned PPCMCCodeEmitter::getSPE4DisEncoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI)
const {
// Encode (imm, reg) as a spe4dis, which has the low 5-bits of (imm / 4)
// as the displacement and the next 5 bits as the register #.
assert(MI.getOperand(OpNo+1).isReg());
uint32_t RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI) << 5;

const MCOperand &MO = MI.getOperand(OpNo);
assert(MO.isImm());
uint32_t Imm = getMachineOpValue(MI, MO, Fixups, STI) >> 2;
return reverseBits(Imm | RegBits) >> 22;
}


unsigned PPCMCCodeEmitter::getSPE2DisEncoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI)
const {
// Encode (imm, reg) as a spe2dis, which has the low 5-bits of (imm / 2)
// as the displacement and the next 5 bits as the register #.
assert(MI.getOperand(OpNo+1).isReg());
uint32_t RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI) << 5;

const MCOperand &MO = MI.getOperand(OpNo);
assert(MO.isImm());
uint32_t Imm = getMachineOpValue(MI, MO, Fixups, STI) >> 1;
return reverseBits(Imm | RegBits) >> 22;
}


unsigned PPCMCCodeEmitter::getTLSRegEncoding(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const {
Expand Down
40 changes: 40 additions & 0 deletions lib/Target/PowerPC/PPCCodeEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ namespace {
unsigned getImm16Encoding(const MachineInstr &MI, unsigned OpNo) const;
unsigned getMemRIEncoding(const MachineInstr &MI, unsigned OpNo) const;
unsigned getMemRIXEncoding(const MachineInstr &MI, unsigned OpNo) const;
unsigned getSPE8DisEncoding(const MachineInstr &MI, unsigned OpNo) const;
unsigned getSPE4DisEncoding(const MachineInstr &MI, unsigned OpNo) const;
unsigned getSPE2DisEncoding(const MachineInstr &MI, unsigned OpNo) const;
unsigned getTLSRegEncoding(const MachineInstr &MI, unsigned OpNo) const;
unsigned getTLSCallEncoding(const MachineInstr &MI, unsigned OpNo) const;

Expand Down Expand Up @@ -261,6 +264,43 @@ unsigned PPCCodeEmitter::getMemRIXEncoding(const MachineInstr &MI,
return RegBits;
}

unsigned PPCCodeEmitter::getSPE8DisEncoding(const MachineInstr &MI, unsigned OpNo) const {
// Encode (imm, reg) as a spe8dis, which has the low 5-bits of (imm / 8)
// as the displacement and the next 5 bits as the register #.
assert(MI.getOperand(OpNo+1).isReg());
uint32_t RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1)) << 5;

const MachineOperand &MO = MI.getOperand(OpNo);
assert(MO.isImm());
uint32_t Imm = getMachineOpValue(MI, MO) >> 3;
return reverseBits(Imm | RegBits) >> 22;
}


unsigned PPCCodeEmitter::getSPE4DisEncoding(const MachineInstr &MI, unsigned OpNo) const {
// Encode (imm, reg) as a spe4dis, which has the low 5-bits of (imm / 4)
// as the displacement and the next 5 bits as the register #.
assert(MI.getOperand(OpNo+1).isReg());
uint32_t RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1)) << 5;

const MachineOperand &MO = MI.getOperand(OpNo);
assert(MO.isImm());
uint32_t Imm = getMachineOpValue(MI, MO) >> 2;
return reverseBits(Imm | RegBits) >> 22;
}


unsigned PPCCodeEmitter::getSPE2DisEncoding(const MachineInstr &MI, unsigned OpNo) const {
// Encode (imm, reg) as a spe2dis, which has the low 5-bits of (imm / 2)
// as the displacement and the next 5 bits as the register #.
assert(MI.getOperand(OpNo+1).isReg());
uint32_t RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1)) << 5;

const MachineOperand &MO = MI.getOperand(OpNo);
assert(MO.isImm());
uint32_t Imm = getMachineOpValue(MI, MO) >> 1;
return reverseBits(Imm | RegBits) >> 22;
}

unsigned PPCCodeEmitter::getTLSRegEncoding(const MachineInstr &MI,
unsigned OpNo) const {
Expand Down
36 changes: 36 additions & 0 deletions lib/Target/PowerPC/PPCInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,27 @@ def PPCDispRIXOperand : AsmOperandClass {
def dispRIX : Operand<iPTR> {
let ParserMatchClass = PPCDispRIXOperand;
}
def PPCDispSPE8Operand : AsmOperandClass {
let Name = "DispSPE8"; let PredicateMethod = "isU8ImmX8";
let RenderMethod = "addImmOperands";
}
def dispSPE8 : Operand<iPTR> {
let ParserMatchClass = PPCDispSPE8Operand;
}
def PPCDispSPE4Operand : AsmOperandClass {
let Name = "DispSPE4"; let PredicateMethod = "isU7ImmX4";
let RenderMethod = "addImmOperands";
}
def dispSPE4 : Operand<iPTR> {
let ParserMatchClass = PPCDispSPE4Operand;
}
def PPCDispSPE2Operand : AsmOperandClass {
let Name = "DispSPE2"; let PredicateMethod = "isU6ImmX2";
let RenderMethod = "addImmOperands";
}
def dispSPE2 : Operand<iPTR> {
let ParserMatchClass = PPCDispSPE2Operand;
}

def memri : Operand<iPTR> {
let PrintMethod = "printMemRegImm";
Expand All @@ -583,6 +604,21 @@ def memrix : Operand<iPTR> { // memri where the imm is 4-aligned.
let EncoderMethod = "getMemRIXEncoding";
let DecoderMethod = "decodeMemRIXOperands";
}
def spe8dis : Operand<iPTR> { // SPE displacement where the imm is 8-aligned.
let PrintMethod = "printMemRegImm";
let MIOperandInfo = (ops dispSPE8:$imm, ptr_rc_nor0:$reg);
let EncoderMethod = "getSPE8DisEncoding";
}
def spe4dis : Operand<iPTR> { // SPE displacement where the imm is 4-aligned.
let PrintMethod = "printMemRegImm";
let MIOperandInfo = (ops dispSPE4:$imm, ptr_rc_nor0:$reg);
let EncoderMethod = "getSPE4DisEncoding";
}
def spe2dis : Operand<iPTR> { // SPE displacement where the imm is 2-aligned.
let PrintMethod = "printMemRegImm";
let MIOperandInfo = (ops dispSPE2:$imm, ptr_rc_nor0:$reg);
let EncoderMethod = "getSPE2DisEncoding";
}

// A single-register address. This is used with the SjLj
// pseudo-instructions.
Expand Down
60 changes: 60 additions & 0 deletions lib/Target/PowerPC/PPCInstrSPE.td
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,68 @@ class EVXForm_3<bits<11> xo, dag OOL, dag IOL, string asmstr,
let Inst{21-31} = xo;
}

class EVXForm_D<bits<11> xo, dag OOL, dag IOL, string asmstr,
InstrItinClass itin> : I<4, OOL, IOL, asmstr, itin> {
bits<5> RT;
bits<21> D;

let Pattern = [];

let Inst{6-10} = RT;
let Inst{20} = D{0};
let Inst{19} = D{1};
let Inst{18} = D{2};
let Inst{17} = D{3};
let Inst{16} = D{4};
let Inst{15} = D{5};
let Inst{14} = D{6};
let Inst{13} = D{7};
let Inst{12} = D{8};
let Inst{11} = D{9};
let Inst{11-20} = D{0-9};
let Inst{21-31} = xo;
}

let Predicates = [HasSPE], isAsmParserOnly = 1 in {

def EVLDD : EVXForm_D<769, (outs gprc:$RT), (ins spe8dis:$dst),
"evldd $RT, $dst", IIC_VecFP>;
def EVLDW : EVXForm_D<771, (outs gprc:$RT), (ins spe8dis:$dst),
"evldw $RT, $dst", IIC_VecFP>;
def EVLDH : EVXForm_D<773, (outs gprc:$RT), (ins spe8dis:$dst),
"evldh $RT, $dst", IIC_VecFP>;
def EVLHHESPLAT : EVXForm_D<777, (outs gprc:$RT), (ins spe2dis:$dst),
"evlhhesplat $RT, $dst", IIC_VecFP>;
def EVLHHOUSPLAT : EVXForm_D<781, (outs gprc:$RT), (ins spe2dis:$dst),
"evlhhousplat $RT, $dst", IIC_VecFP>;
def EVLHHOSSPLAT : EVXForm_D<783, (outs gprc:$RT), (ins spe2dis:$dst),
"evlhhossplat $RT, $dst", IIC_VecFP>;
def EVLWHE : EVXForm_D<785, (outs gprc:$RT), (ins spe4dis:$dst),
"evlwhe $RT, $dst", IIC_VecFP>;
def EVLWHOU : EVXForm_D<789, (outs gprc:$RT), (ins spe4dis:$dst),
"evlwhou $RT, $dst", IIC_VecFP>;
def EVLWHOS : EVXForm_D<791, (outs gprc:$RT), (ins spe4dis:$dst),
"evlwhos $RT, $dst", IIC_VecFP>;
def EVLWWSPLAT : EVXForm_D<793, (outs gprc:$RT), (ins spe4dis:$dst),
"evlwwsplat $RT, $dst", IIC_VecFP>;
def EVLWHSPLAT : EVXForm_D<797, (outs gprc:$RT), (ins spe4dis:$dst),
"evlwhsplat $RT, $dst", IIC_VecFP>;

def EVSTDD : EVXForm_D<801, (outs), (ins gprc:$RT, spe8dis:$dst),
"evstdd $RT, $dst", IIC_VecFP>;
def EVSTDH : EVXForm_D<805, (outs), (ins gprc:$RT, spe8dis:$dst),
"evstdh $RT, $dst", IIC_VecFP>;
def EVSTDW : EVXForm_D<803, (outs), (ins gprc:$RT, spe8dis:$dst),
"evstdw $RT, $dst", IIC_VecFP>;
def EVSTWHE : EVXForm_D<817, (outs), (ins gprc:$RT, spe4dis:$dst),
"evstwhe $RT, $dst", IIC_VecFP>;
def EVSTWHO : EVXForm_D<821, (outs), (ins gprc:$RT, spe4dis:$dst),
"evstwho $RT, $dst", IIC_VecFP>;
def EVSTWWE : EVXForm_D<825, (outs), (ins gprc:$RT, spe4dis:$dst),
"evstwwe $RT, $dst", IIC_VecFP>;
def EVSTWWO : EVXForm_D<829, (outs), (ins gprc:$RT, spe4dis:$dst),
"evstwwo $RT, $dst", IIC_VecFP>;

def EVMRA : EVXForm_1<1220, (outs gprc:$RT), (ins gprc:$RA),
"evmra $RT, $RA", IIC_VecFP> {
let RB = 0;
Expand Down
Loading

0 comments on commit c9def6b

Please sign in to comment.