Skip to content

Commit ad64946

Browse files
authored
[SPARC][IAS] Add support for call dest, imm form (#119078)
This follows GCC behavior of allowing a trailing immediate, that is ignored by the assembler.
1 parent 5e1f87e commit ad64946

File tree

4 files changed

+71
-7
lines changed

4 files changed

+71
-7
lines changed

llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ class SparcOperand : public MCParsedAsmOperand {
220220
k_MemoryImm,
221221
k_ASITag,
222222
k_PrefetchTag,
223+
k_TailRelocSym, // Special kind of immediate for TLS relocation purposes.
223224
} Kind;
224225

225226
SMLoc StartLoc, EndLoc;
@@ -265,7 +266,7 @@ class SparcOperand : public MCParsedAsmOperand {
265266
bool isMembarTag() const { return Kind == k_Immediate; }
266267
bool isASITag() const { return Kind == k_ASITag; }
267268
bool isPrefetchTag() const { return Kind == k_PrefetchTag; }
268-
bool isTailRelocSym() const { return Kind == k_Immediate; }
269+
bool isTailRelocSym() const { return Kind == k_TailRelocSym; }
269270

270271
bool isCallTarget() const {
271272
if (!isImm())
@@ -354,6 +355,11 @@ class SparcOperand : public MCParsedAsmOperand {
354355
return Prefetch;
355356
}
356357

358+
const MCExpr *getTailRelocSym() const {
359+
assert((Kind == k_TailRelocSym) && "Invalid access!");
360+
return Imm.Val;
361+
}
362+
357363
/// getStartLoc - Get the location of the first token of this operand.
358364
SMLoc getStartLoc() const override {
359365
return StartLoc;
@@ -380,6 +386,9 @@ class SparcOperand : public MCParsedAsmOperand {
380386
case k_PrefetchTag:
381387
OS << "Prefetch tag: " << getPrefetchTag() << "\n";
382388
break;
389+
case k_TailRelocSym:
390+
OS << "TailReloc: " << getTailRelocSym() << "\n";
391+
break;
383392
}
384393
}
385394

@@ -454,7 +463,7 @@ class SparcOperand : public MCParsedAsmOperand {
454463

455464
void addTailRelocSymOperands(MCInst &Inst, unsigned N) const {
456465
assert(N == 1 && "Invalid number of operands!");
457-
addExpr(Inst, getImm());
466+
addExpr(Inst, getTailRelocSym());
458467
}
459468

460469
static std::unique_ptr<SparcOperand> CreateToken(StringRef Str, SMLoc S) {
@@ -503,6 +512,15 @@ class SparcOperand : public MCParsedAsmOperand {
503512
return Op;
504513
}
505514

515+
static std::unique_ptr<SparcOperand> CreateTailRelocSym(const MCExpr *Val,
516+
SMLoc S, SMLoc E) {
517+
auto Op = std::make_unique<SparcOperand>(k_TailRelocSym);
518+
Op->Imm.Val = Val;
519+
Op->StartLoc = S;
520+
Op->EndLoc = E;
521+
return Op;
522+
}
523+
506524
static bool MorphToIntPairReg(SparcOperand &Op) {
507525
unsigned Reg = Op.getReg();
508526
assert(Op.Reg.Kind == rk_IntReg);
@@ -1070,7 +1088,7 @@ ParseStatus SparcAsmParser::parseTailRelocSym(OperandVector &Operands) {
10701088
};
10711089

10721090
if (getLexer().getKind() != AsmToken::Percent)
1073-
return Error(getLoc(), "expected '%' for operand modifier");
1091+
return ParseStatus::NoMatch;
10741092

10751093
const AsmToken Tok = Parser.getTok();
10761094
getParser().Lex(); // Eat '%'
@@ -1099,7 +1117,7 @@ ParseStatus SparcAsmParser::parseTailRelocSym(OperandVector &Operands) {
10991117
return ParseStatus::Failure;
11001118

11011119
const MCExpr *Val = adjustPICRelocation(VK, SubExpr);
1102-
Operands.push_back(SparcOperand::CreateImm(Val, S, E));
1120+
Operands.push_back(SparcOperand::CreateTailRelocSym(Val, S, E));
11031121
return ParseStatus::Success;
11041122
}
11051123

llvm/lib/Target/Sparc/DelaySlotFiller.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,8 @@ void Filler::insertCallDefsUses(MachineBasicBlock::iterator MI,
309309

310310
switch(MI->getOpcode()) {
311311
default: llvm_unreachable("Unknown opcode.");
312-
case SP::CALL: break;
312+
case SP::CALL:
313+
break;
313314
case SP::CALLrr:
314315
case SP::CALLri:
315316
assert(MI->getNumOperands() >= 2);
@@ -371,9 +372,13 @@ bool Filler::needsUnimp(MachineBasicBlock::iterator I, unsigned &StructSize)
371372
unsigned structSizeOpNum = 0;
372373
switch (I->getOpcode()) {
373374
default: llvm_unreachable("Unknown call opcode.");
374-
case SP::CALL: structSizeOpNum = 1; break;
375+
case SP::CALL:
376+
structSizeOpNum = 1;
377+
break;
375378
case SP::CALLrr:
376-
case SP::CALLri: structSizeOpNum = 2; break;
379+
case SP::CALLri:
380+
structSizeOpNum = 2;
381+
break;
377382
case SP::TLS_CALL: return false;
378383
case SP::TAIL_CALLri:
379384
case SP::TAIL_CALL: return false;

llvm/lib/Target/Sparc/SparcInstrInfo.td

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1036,6 +1036,17 @@ let Uses = [O6],
10361036
let Inst{29-0} = disp;
10371037
}
10381038

1039+
// call with trailing imm argument.
1040+
// The imm argument is discarded.
1041+
let isAsmParserOnly = 1 in {
1042+
def CALLi : InstSP<(outs), (ins calltarget:$disp, i32imm:$imm),
1043+
"call $disp, $imm", []> {
1044+
bits<30> disp;
1045+
let op = 1;
1046+
let Inst{29-0} = disp;
1047+
}
1048+
}
1049+
10391050
// indirect calls: special cases of JMPL.
10401051
let isCodeGenOnly = 1, rd = 15 in {
10411052
def CALLrr : F3_1<2, 0b111000,
@@ -1049,6 +1060,15 @@ let Uses = [O6],
10491060
[(call ADDRri:$addr)],
10501061
IIC_jmp_or_call>;
10511062
}
1063+
1064+
let isAsmParserOnly = 1, rd = 15 in {
1065+
def CALLrri : F3_1<2, 0b111000,
1066+
(outs), (ins (MEMrr $rs1, $rs2):$addr, i32imm:$imm),
1067+
"call $addr, $imm", []>;
1068+
def CALLrii : F3_2<2, 0b111000,
1069+
(outs), (ins (MEMri $rs1, $simm13):$addr, i32imm:$imm),
1070+
"call $addr, $imm", []>;
1071+
}
10521072
}
10531073

10541074
// Section B.25 - Jump and Link Instruction

llvm/test/MC/Sparc/sparc-ctrl-instructions.s

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,44 @@
55
! CHECK: ! fixup A - offset: 0, value: foo, kind: fixup_sparc_call30
66
call foo
77

8+
! CHECK: call foo, 0 ! encoding: [0b01AAAAAA,A,A,A]
9+
! CHECK: ! fixup A - offset: 0, value: foo, kind: fixup_sparc_call30
10+
call foo, 0
11+
812
! CHECK: call %g1+%i2 ! encoding: [0x9f,0xc0,0x40,0x1a]
913
call %g1 + %i2
1014

15+
! CHECK: call %g1+%i2, 1 ! encoding: [0x9f,0xc0,0x40,0x1a]
16+
call %g1 + %i2, 1
17+
1118
! CHECK: call %o1+8 ! encoding: [0x9f,0xc2,0x60,0x08]
1219
call %o1 + 8
1320

21+
! CHECK: call %o1+8, 2 ! encoding: [0x9f,0xc2,0x60,0x08]
22+
call %o1 + 8, 2
23+
1424
! CHECK: call %g1 ! encoding: [0x9f,0xc0,0x40,0x00]
1525
call %g1
1626

27+
! CHECK: call %g1, 3 ! encoding: [0x9f,0xc0,0x40,0x00]
28+
call %g1, 3
29+
1730
! CHECK: call %g1+%lo(sym) ! encoding: [0x9f,0xc0,0b011000AA,A]
1831
! CHECK-NEXT: ! fixup A - offset: 0, value: %lo(sym), kind: fixup_sparc_lo10
1932
call %g1+%lo(sym)
2033

34+
! CHECK: call %g1+%lo(sym), 4 ! encoding: [0x9f,0xc0,0b011000AA,A]
35+
! CHECK-NEXT: ! fixup A - offset: 0, value: %lo(sym), kind: fixup_sparc_lo10
36+
call %g1+%lo(sym), 4
37+
2138
! CHECK-LABEL: .Ltmp0:
2239
! CHECK: call .Ltmp0-4 ! encoding: [0b01AAAAAA,A,A,A]
2340
call . - 4
2441

42+
! CHECK-LABEL: .Ltmp1:
43+
! CHECK: call .Ltmp1-4, 5 ! encoding: [0b01AAAAAA,A,A,A]
44+
call . - 4, 5
45+
2546
! CHECK: jmp %g1+%i2 ! encoding: [0x81,0xc0,0x40,0x1a]
2647
jmp %g1 + %i2
2748

0 commit comments

Comments
 (0)