Skip to content

Commit ccafe05

Browse files
committed
Sparc: support the "set" synthetic instruction.
This pseudo-instruction expands into 'sethi' and 'or' instructions, or, just one of them, if the other isn't necessary for a given value. Differential Revision: http://reviews.llvm.org/D9089 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@237585 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 292c78b commit ccafe05

File tree

4 files changed

+91
-2
lines changed

4 files changed

+91
-2
lines changed

lib/Target/Sparc/AsmParser/SparcAsmParser.cpp

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ class SparcAsmParser : public MCTargetAsmParser {
7777
bool parseDirectiveWord(unsigned Size, SMLoc L);
7878

7979
bool is64Bit() const { return STI.getTargetTriple().startswith("sparcv9"); }
80+
81+
void expandSET(MCInst &Inst, SMLoc IDLoc,
82+
SmallVectorImpl<MCInst> &Instructions);
83+
8084
public:
8185
SparcAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
8286
const MCInstrInfo &MII,
@@ -392,6 +396,49 @@ class SparcOperand : public MCParsedAsmOperand {
392396

393397
} // end namespace
394398

399+
void SparcAsmParser::expandSET(MCInst &Inst, SMLoc IDLoc,
400+
SmallVectorImpl<MCInst> &Instructions) {
401+
MCOperand MCRegOp = Inst.getOperand(0);
402+
MCOperand MCValOp = Inst.getOperand(1);
403+
assert(MCRegOp.isReg());
404+
assert(MCValOp.isImm() || MCValOp.isExpr());
405+
406+
// the imm operand can be either an expression or an immediate.
407+
bool IsImm = Inst.getOperand(1).isImm();
408+
uint64_t ImmValue = IsImm ? MCValOp.getImm() : 0;
409+
const MCExpr *ValExpr;
410+
if (IsImm)
411+
ValExpr = MCConstantExpr::Create(ImmValue, getContext());
412+
else
413+
ValExpr = MCValOp.getExpr();
414+
415+
MCOperand PrevReg = MCOperand::createReg(Sparc::G0);
416+
417+
if (!IsImm || (ImmValue & ~0x1fff)) {
418+
MCInst TmpInst;
419+
const MCExpr *Expr =
420+
SparcMCExpr::Create(SparcMCExpr::VK_Sparc_HI, ValExpr, getContext());
421+
TmpInst.setLoc(IDLoc);
422+
TmpInst.setOpcode(SP::SETHIi);
423+
TmpInst.addOperand(MCRegOp);
424+
TmpInst.addOperand(MCOperand::createExpr(Expr));
425+
Instructions.push_back(TmpInst);
426+
PrevReg = MCRegOp;
427+
}
428+
429+
if (!IsImm || ((ImmValue & 0x1fff) != 0 || ImmValue == 0)) {
430+
MCInst TmpInst;
431+
const MCExpr *Expr =
432+
SparcMCExpr::Create(SparcMCExpr::VK_Sparc_LO, ValExpr, getContext());
433+
TmpInst.setLoc(IDLoc);
434+
TmpInst.setOpcode(SP::ORri);
435+
TmpInst.addOperand(MCRegOp);
436+
TmpInst.addOperand(PrevReg);
437+
TmpInst.addOperand(MCOperand::createExpr(Expr));
438+
Instructions.push_back(TmpInst);
439+
}
440+
}
441+
395442
bool SparcAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
396443
OperandVector &Operands,
397444
MCStreamer &Out,
@@ -403,8 +450,19 @@ bool SparcAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
403450
MatchingInlineAsm);
404451
switch (MatchResult) {
405452
case Match_Success: {
406-
Inst.setLoc(IDLoc);
407-
Out.EmitInstruction(Inst, STI);
453+
switch (Inst.getOpcode()) {
454+
default:
455+
Inst.setLoc(IDLoc);
456+
Instructions.push_back(Inst);
457+
break;
458+
case SP::SET:
459+
expandSET(Inst, IDLoc, Instructions);
460+
break;
461+
}
462+
463+
for (const MCInst &I : Instructions) {
464+
Out.EmitInstruction(I, STI);
465+
}
408466
return false;
409467
}
410468

lib/Target/Sparc/SparcInstrAliases.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,11 @@ def : InstAlias<"mov $rs2, $rd", (ORrr IntRegs:$rd, G0, IntRegs:$rs2)>;
306306
// mov simm13, rd -> or %g0, simm13, rd
307307
def : InstAlias<"mov $simm13, $rd", (ORri IntRegs:$rd, G0, i32imm:$simm13)>;
308308

309+
// set value, rd
310+
// (turns into a sequence of sethi+or, depending on the value)
311+
// def : InstAlias<"set $val, $rd", (ORri IntRegs:$rd, (SETHIi (HI22 imm:$val)), (LO10 imm:$val))>;
312+
def SET : AsmPseudoInst<(outs IntRegs:$rd), (ins i32imm:$val), "set $val, $rd">;
313+
309314
// restore -> restore %g0, %g0, %g0
310315
def : InstAlias<"restore", (RESTORErr G0, G0, G0)>;
311316

@@ -329,3 +334,4 @@ def : InstAlias<"fcmped $rs1, $rs2", (V9FCMPED FCC0, DFPRegs:$rs1,
329334
def : InstAlias<"fcmpeq $rs1, $rs2", (V9FCMPEQ FCC0, QFPRegs:$rs1,
330335
QFPRegs:$rs2)>,
331336
Requires<[HasHardQuad]>;
337+

lib/Target/Sparc/SparcInstrFormats.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,3 +331,11 @@ class TRAPSPri<bits<6> op3Val, dag outs, dag ins, string asmstr,
331331
let Inst{10-8} = 0;
332332
let Inst{7-0} = imm;
333333
}
334+
335+
// Pseudo-instructions for alternate assembly syntax (never used by codegen).
336+
// These are aliases that require C++ handling to convert to the target
337+
// instruction, while InstAliases can be handled directly by tblgen.
338+
class AsmPseudoInst<dag outs, dag ins, string asm>
339+
: InstSP<outs, ins, asm, []> {
340+
let isPseudo = 1;
341+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
! RUN: llvm-mc %s -arch=sparc -show-encoding | FileCheck %s
2+
! RUN: llvm-mc %s -arch=sparcv9 -show-encoding | FileCheck %s
3+
4+
! Section A.3 Synthetic Instructions
5+
! CHECK: sethi %hi(40000), %g1 ! encoding: [0x03,0b00AAAAAA,A,A]
6+
! CHECK: ! fixup A - offset: 0, value: %hi(40000), kind: fixup_sparc_hi22
7+
! CHECK: or %g1, %lo(40000), %g1 ! encoding: [0x82,0x10,0b011000AA,A]
8+
! CHECK: ! fixup A - offset: 0, value: %lo(40000), kind: fixup_sparc_lo10
9+
set 40000, %g1
10+
! CHECK: mov %lo(1), %g1 ! encoding: [0x82,0x10,0b001000AA,A]
11+
! CHECK: ! fixup A - offset: 0, value: %lo(1), kind: fixup_sparc_lo10
12+
set 1, %g1
13+
14+
! CHECK: sethi %hi(32768), %g1 ! encoding: [0x03,0b00AAAAAA,A,A]
15+
! CHECK: ! fixup A - offset: 0, value: %hi(32768), kind: fixup_sparc_hi22
16+
set 32768, %g1
17+

0 commit comments

Comments
 (0)