Skip to content

Commit 0123300

Browse files
PavelKopylakiramenai
authored andcommitted
[EraVM] Split assembler syntax for direct/indirect code references.
1. code[@symbol + reg + imm] Denotes indirect code reference. Loads a word from the code page at the offset (measured in words): "@symbol + reg + imm". 2. @symbol + imm Just denotes the expression value itself. @symbol is resolved as an offset to the label measured in instructions. add @.OUTLINED_FUNCTION_RET2[0], r0, stack[-1]
1 parent ad87856 commit 0123300

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+551
-567
lines changed

lld/test/ELF/eravm-binary-layout.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
.text
99
nop stack+=[2 + r0]
10-
add @glob_initializer[0], r0, stack[@glob]
10+
add code[@glob_initializer], r0, stack[@glob]
1111

1212
.globl get_glob
1313
get_glob:

lld/test/ELF/eravm-code-reloc.s

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ foo_local:
6868
caller_g:
6969
near_call r1, @foo, @handler
7070
far_call r3, r4, @foo
71-
add @.OUTLINED_FUNCTION_RET0[0], r0, stack-[1]
71+
add @.OUTLINED_FUNCTION_RET0, r0, stack-[1]
7272
jump @foo_local
7373
.OUTLINED_FUNCTION_RET0:
7474
jump @label
@@ -77,15 +77,15 @@ caller_g:
7777
ret.panic.to_label @label
7878
.globl label
7979
label:
80-
jump @jump_table[1]
80+
jump code[@jump_table + 1]
8181
ret
8282
; INPUT-LABEL: <caller_g>:
8383
; INPUT-NEXT: 00 00 00 00 00 01 04 0f near_call r1, 0, 0
8484
; INPUT-NEXT: R_ERAVM_16_SCALE_8 handler
8585
; INPUT-NEXT: R_ERAVM_16_SCALE_8 foo
8686
; INPUT-NEXT: 00 00 00 00 00 43 04 21 far_call r3, r4, 0
8787
; INPUT-NEXT: R_ERAVM_16_SCALE_8 foo
88-
; INPUT-NEXT: 00 01 00 00 00 00 00 45 add code[0], r0, stack-[1 + r0]
88+
; INPUT-NEXT: 00 01 00 00 00 00 00 3d add 0, r0, stack-[1 + r0]
8989
; INPUT-NEXT: R_ERAVM_16_SCALE_8 .text+0x40
9090
; INPUT-NEXT: 00 00 00 00 00 00 01 3d jump 0
9191
; INPUT-NEXT: R_ERAVM_16_SCALE_8 .text+0x18
@@ -105,7 +105,7 @@ label:
105105
; OUTPUT-LABEL: <caller_g>:
106106
; OUTPUT-NEXT: 00 12 00 13 00 01 04 0f near_call r1, 19, 18
107107
; OUTPUT-NEXT: 00 00 00 13 00 43 04 21 far_call r3, r4, 19
108-
; OUTPUT-NEXT: 00 01 00 18 00 00 00 45 add code[24], r0, stack-[1 + r0]
108+
; OUTPUT-NEXT: 00 01 00 18 00 00 00 3d add 24, r0, stack-[1 + r0]
109109
; OUTPUT-NEXT: 00 00 00 13 00 00 01 3d jump 19
110110
; OUTPUT-NEXT: 00 00 00 1c 00 00 01 3d jump 28
111111
; OUTPUT-NEXT: 00 00 00 1c 00 01 04 2e ret.ok.to_label r1, 28
@@ -127,7 +127,7 @@ caller_l:
127127
ret.panic.to_label @label_local
128128
.local label_local
129129
label_local:
130-
jump @jump_table_local[1]
130+
jump code[@jump_table_local + 1]
131131
ret
132132

133133
; INPUT-LABEL: <caller_l>:

lld/test/ELF/eravm-data-reloc.s

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,9 @@ array_const_local:
7575
.text
7676
.p2align 3
7777
reloc_src_g:
78-
add @scalar_const[0], r1, r1
78+
add code[@scalar_const], r1, r1
7979
add stack[@scalar_var], r1, r1
80-
add @array_const[1], r1, r1
80+
add code[@array_const + 1], r1, r1
8181
add stack[@array_var + 1], r1, r1
8282
ret
8383
; INPUT-LABEL: <reloc_src_g>:
@@ -99,9 +99,9 @@ reloc_src_g:
9999
; OUTPUT-NEXT: 00 00 00 00 00 01 04 2d ret
100100

101101
reloc_src_l:
102-
add @scalar_const_local[0], r1, r1
102+
add code[@scalar_const_local], r1, r1
103103
add stack[@scalar_var_local], r1, r1
104-
add @array_const_local[1], r1, r1
104+
add code[@array_const_local + 1], r1, r1
105105
add stack[@array_var_local + 1], r1, r1
106106
ret
107107
; INPUT-LABEL: <reloc_src_l>:
@@ -155,9 +155,9 @@ reloc_dst_l:
155155
; OUTPUT-NEXT: 00 00 00 00 00 01 04 2d ret
156156

157157
reloc_both_g:
158-
add @scalar_const[0], r1, stack[@array_var + 1]
158+
add code[@scalar_const], r1, stack[@array_var + 1]
159159
add stack[@scalar_var], r1, stack[@array_var + 1]
160-
add @array_const[1], r1, stack[@scalar_var]
160+
add code[@array_const + 1], r1, stack[@scalar_var]
161161
add stack[@array_var + 1], r1, stack[@scalar_var]
162162
ret
163163
; INPUT-LABEL: <reloc_both_g>:
@@ -183,9 +183,9 @@ reloc_both_g:
183183
; OUTPUT-NEXT: 00 00 00 00 00 01 04 2d ret
184184

185185
reloc_both_l:
186-
add @scalar_const_local[0], r1, stack[@array_var_local + 1]
186+
add code[@scalar_const_local], r1, stack[@array_var_local + 1]
187187
add stack[@scalar_var_local], r1, stack[@array_var_local + 1]
188-
add @array_const_local[1], r1, stack[@scalar_var_local]
188+
add code[@array_const_local + 1], r1, stack[@scalar_var_local]
189189
add stack[@array_var_local + 1], r1, stack[@scalar_var_local]
190190
ret
191191
; INPUT-LABEL: <reloc_both_l>:

llvm/lib/Target/EraVM/AsmParser/EraVMAsmParser.cpp

Lines changed: 62 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ class EraVMAsmParser : public MCTargetAsmParser {
6464
bool parseRegOperand(OperandVector &Operands);
6565
ParseStatus tryParseUImm16Operand(OperandVector &Operands);
6666
ParseStatus tryParseJumpTargetOperand(OperandVector &Operands);
67+
bool parseAddend(int &Addend, bool SignRequired);
6768
bool parseRegisterWithAddend(MCRegister &RegNo, MCSymbol *&Symbol,
6869
int &Addend);
6970
bool parseOperand(StringRef Mnemonic, OperandVector &Operands);
@@ -416,6 +417,31 @@ bool EraVMAsmParser::parseRegOperand(OperandVector &Operands) {
416417
}
417418

418419
ParseStatus EraVMAsmParser::tryParseUImm16Operand(OperandVector &Operands) {
420+
// First check if this is a symbol + addend.
421+
if (getTok().is(AsmToken::At)) {
422+
MCSymbol *Symbol = nullptr;
423+
SMLoc StartOfOperand = getLexer().getLoc();
424+
int Addend = 0;
425+
426+
Lex(); // eat "@" token
427+
Symbol = getContext().getOrCreateSymbol(getTok().getString());
428+
Lex(); // eat symbol name
429+
if (getTok().is(AsmToken::Plus) || getTok().is(AsmToken::Minus))
430+
if (parseAddend(Addend, /*SignRequired=*/true))
431+
return ParseStatus::Failure;
432+
433+
const MCExpr *Expr = MCSymbolRefExpr::create(Symbol, getContext());
434+
// FIXME Should we support negative addends?
435+
Addend &= (unsigned)0xffff;
436+
if (Addend) {
437+
const MCExpr *AddendExpr = createConstant(Addend);
438+
Expr = MCBinaryExpr::createAdd(Expr, AddendExpr, getContext());
439+
}
440+
Operands.push_back(
441+
EraVMOperand::CreateImm(Expr, StartOfOperand, getTok().getEndLoc()));
442+
return ParseStatus::Success;
443+
}
444+
419445
if (getLexer().is(AsmToken::Minus) &&
420446
getLexer().peekTok().is(AsmToken::Integer)) {
421447
TokError("negative immediate operands are not supported");
@@ -459,34 +485,33 @@ ParseStatus EraVMAsmParser::tryParseJumpTargetOperand(OperandVector &Operands) {
459485
return ParseStatus::Success;
460486
}
461487

462-
bool EraVMAsmParser::parseRegisterWithAddend(MCRegister &RegNo,
463-
MCSymbol *&Symbol, int &Addend) {
464-
auto ParseAddend = [this, &Addend](bool SignRequired) {
465-
int Multiplier = 1;
466-
467-
switch (getTok().getKind()) {
468-
case AsmToken::Plus:
469-
Multiplier = 1;
470-
Lex(); // eat "+" token
471-
break;
472-
case AsmToken::Minus:
473-
Multiplier = -1;
474-
Lex(); // eat "-" token
475-
break;
476-
default:
477-
if (SignRequired)
478-
return TokError("'+' or '-' expected");
479-
break;
480-
}
488+
bool EraVMAsmParser::parseAddend(int &Addend, bool SignRequired) {
489+
int Multiplier = 1;
490+
switch (getTok().getKind()) {
491+
case AsmToken::Plus:
492+
Multiplier = 1;
493+
Lex(); // eat "+" token
494+
break;
495+
case AsmToken::Minus:
496+
Multiplier = -1;
497+
Lex(); // eat "-" token
498+
break;
499+
default:
500+
if (SignRequired)
501+
return TokError("'+' or '-' expected");
502+
break;
503+
}
481504

482-
if (!getLexer().is(AsmToken::Integer))
483-
return TokError("integer addend expected");
484-
Addend = Multiplier * getTok().getIntVal();
485-
Lex(); // eat integer token
505+
if (!getLexer().is(AsmToken::Integer))
506+
return TokError("integer addend expected");
507+
Addend = Multiplier * getTok().getIntVal();
508+
Lex(); // eat integer token
486509

487-
return false;
488-
};
510+
return false;
511+
}
489512

513+
bool EraVMAsmParser::parseRegisterWithAddend(MCRegister &RegNo,
514+
MCSymbol *&Symbol, int &Addend) {
490515
auto ParseRegister = [this, &RegNo]() {
491516
SMLoc S, E;
492517
if (tryParseRegister(RegNo, S, E).isNoMatch())
@@ -526,10 +551,10 @@ bool EraVMAsmParser::parseRegisterWithAddend(MCRegister &RegNo,
526551
return true;
527552
if (getTok().is(AsmToken::RBrac))
528553
return false; // keep "]" token for the caller
529-
return ParseAddend(/*SignRequired=*/true);
554+
return parseAddend(Addend, /*SignRequired=*/true);
530555
}
531556

532-
if (ParseAddend(/*SignRequired=*/false))
557+
if (parseAddend(Addend, /*SignRequired=*/false))
533558
return true;
534559
if (getTok().is(AsmToken::RBrac))
535560
return false; // keep "]" token for the caller
@@ -628,33 +653,18 @@ ParseStatus EraVMAsmParser::tryParseStackOperand(OperandVector &Operands) {
628653

629654
ParseStatus EraVMAsmParser::tryParseCodeOperand(OperandVector &Operands) {
630655
SMLoc StartOfOperand = getLexer().getLoc();
631-
MCSymbol *Symbol = nullptr;
632656
MCSymbol *SymbolInSubscript = nullptr;
633657
MCRegister RegNo = 0;
634658
int Addend = 0;
635659

636-
// Decide if this is a code operand
637-
SmallVector<AsmToken, 2> PeekedTokens(2);
638-
getLexer().peekTokens(PeekedTokens);
639-
if (getTok().is(AsmToken::At)) {
640-
// "@symbol_name[...]"
641-
if (!PeekedTokens[0].is(AsmToken::Identifier) ||
642-
!PeekedTokens[1].is(AsmToken::LBrac))
643-
return ParseStatus::NoMatch;
644-
645-
Lex(); // eat "@" token
646-
Symbol = getContext().getOrCreateSymbol(getTok().getString());
647-
Lex(); // eat constant symbol name
648-
Lex(); // eat "[" token
649-
} else {
650-
// "code[...]"
651-
if (!getTok().is(AsmToken::Identifier) ||
652-
!PeekedTokens[0].is(AsmToken::LBrac) || getTok().getString() != "code")
653-
return ParseStatus::NoMatch;
660+
// "code[...]"
661+
if (!getTok().is(AsmToken::Identifier) ||
662+
!getLexer().peekTok().is(AsmToken::LBrac) ||
663+
getTok().getString() != "code")
664+
return ParseStatus::NoMatch;
654665

655-
Lex(); // eat "code" token
656-
Lex(); // eat "[" token
657-
}
666+
Lex(); // eat "code" token
667+
Lex(); // eat "[" token
658668

659669
if (parseRegisterWithAddend(RegNo, SymbolInSubscript, Addend))
660670
return ParseStatus::Failure;
@@ -665,21 +675,9 @@ ParseStatus EraVMAsmParser::tryParseCodeOperand(OperandVector &Operands) {
665675
if (parseToken(AsmToken::RBrac, "']' expected"))
666676
return ParseStatus::Failure;
667677

668-
if (Symbol) {
669-
// @symbol_name[reg + imm]
670-
if (SymbolInSubscript) {
671-
Error(StartOfOperand, "two symbols in a single operand");
672-
return ParseStatus::Failure;
673-
}
674-
Operands.push_back(EraVMOperand::CreateMem(
675-
&getContext(), EraVM::OperandCode, RegNo, Symbol, Addend,
676-
StartOfOperand, getTok().getEndLoc()));
677-
} else {
678-
// code[...]
679-
Operands.push_back(EraVMOperand::CreateMem(
680-
&getContext(), EraVM::OperandCode, RegNo, SymbolInSubscript, Addend,
681-
StartOfOperand, getTok().getEndLoc()));
682-
}
678+
Operands.push_back(EraVMOperand::CreateMem(
679+
&getContext(), EraVM::OperandCode, RegNo, SymbolInSubscript, Addend,
680+
StartOfOperand, getTok().getEndLoc()));
683681

684682
return ParseStatus::Success;
685683
}

llvm/lib/Target/EraVM/EraVMInstrInfo.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1127,9 +1127,8 @@ MachineBasicBlock::iterator EraVMInstrInfo::insertOutlinedCall(
11271127
It->setPostInstrSymbol(MF, RetSym);
11281128

11291129
// Add instruction to store return address onto the top of the stack.
1130-
BuildMI(MBB, It, DL, get(EraVM::ADDcrs_s))
1130+
BuildMI(MBB, It, DL, get(EraVM::ADDirs_s))
11311131
.addSym(RetSym, EraVMII::MO_SYM_RET_ADDRESS)
1132-
.addImm(0 /* RetSymOffset */)
11331132
.addReg(EraVM::R0)
11341133
.addReg(EraVM::SP)
11351134
.addImm(0 /* AMBase2 */)

llvm/lib/Target/EraVM/MCTargetDesc/EraVMELFObjectWriter.cpp

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -39,32 +39,8 @@ class EraVMELFObjectWriter : public MCELFObjectTargetWriter {
3939
const MCFixup &Fixup, bool IsPCRel) const override {
4040
// Translate fixup kind to ELF relocation type.
4141
switch (Fixup.getTargetKind()) {
42-
case EraVM::fixup_16_scale_32: {
43-
// There may be cases where the relocation symbol is in the code,
44-
// for example:
45-
//
46-
// add @.OUTLINED_FUNCTION_RET0[0], r0, stack-[1]
47-
// jump @OUTLINED_FUNCTION_0
48-
// .OUTLINED_FUNCTION_RET0:
49-
// jump.ge @.BB1_16
50-
// jump @.BB1_23
51-
//
52-
// Here the .OUTLINED_FUNCTION_RET0[0] represents the code offset,
53-
// measured in 8-byte units.
54-
// In such cases the actual relocation type should be R_ERAVM_16_SCALE_8.
55-
if (const MCSymbolRefExpr *A = Target.getSymA()) {
56-
const MCSymbol &Sym = A->getSymbol();
57-
assert(Sym.isDefined());
58-
MCSection &Section = Sym.getSection();
59-
const MCSectionELF *SectionELF = dyn_cast<MCSectionELF>(&Section);
60-
assert(SectionELF && "Null section for reloc symbol");
61-
62-
unsigned Flags = SectionELF->getFlags();
63-
if ((Flags & ELF::SHF_ALLOC) && (Flags & ELF::SHF_EXECINSTR))
64-
return ELF::R_ERAVM_16_SCALE_8;
65-
}
42+
case EraVM::fixup_16_scale_32:
6643
return ELF::R_ERAVM_16_SCALE_32;
67-
}
6844
case EraVM::fixup_16_scale_8:
6945
return ELF::R_ERAVM_16_SCALE_8;
7046
default:

llvm/lib/Target/EraVM/MCTargetDesc/EraVMInstPrinter.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -114,25 +114,28 @@ void EraVMInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
114114
if (BaseReg == EraVM::R0)
115115
BaseReg = 0;
116116

117-
if (Symbol)
118-
O << "@" << Symbol->getName() << "[";
119-
else
120-
O << "code[";
117+
O << "code[";
121118

122-
if (!BaseReg && !Addend)
123-
O << "0";
119+
if (Symbol)
120+
O << "@" << Symbol->getName();
124121

125-
if (BaseReg)
122+
if (BaseReg) {
123+
if (Symbol)
124+
O << "+";
126125
O << getRegisterName(BaseReg);
126+
}
127127

128128
if (Addend) {
129129
if (Addend < 0)
130130
O << "-";
131-
else if (BaseReg)
131+
else if (Symbol || BaseReg)
132132
O << "+";
133133
O << std::abs(Addend);
134134
}
135135

136+
if (!Symbol && !BaseReg && !Addend)
137+
O << "0";
138+
136139
O << "]";
137140
}
138141

llvm/lib/Target/EraVM/MCTargetDesc/EraVMMCCodeEmitter.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,13 @@ EraVMMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO,
154154
return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
155155
if (MO.isImm())
156156
return MO.getImm();
157+
if (MO.isExpr()) {
158+
// This corresponds to the cases where the operand
159+
// is an expression of the form: @symbol + imm.
160+
auto FK = static_cast<MCFixupKind>(EraVM::fixup_16_scale_8);
161+
Fixups.push_back(MCFixup::create(2, MO.getExpr(), FK, MI.getLoc()));
162+
return 0;
163+
}
157164

158165
llvm_unreachable("Unexpected generic operand type");
159166
}

llvm/test/CodeGen/EraVM/add.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ define i256 @addirr(i256 %rs1) nounwind {
2121

2222
; CHECK-LABEL: addcrr
2323
define i256 @addcrr(i256 %rs1) nounwind {
24-
; CHECK: add @val[0], r1, r1
24+
; CHECK: add code[@val], r1, r1
2525
%val = load i256, i256 addrspace(4)* @val
2626
%res = add i256 %rs1, %val
2727
ret i256 %res
@@ -57,7 +57,7 @@ define void @addirs(i256 %rs1) nounwind {
5757
; CHECK-LABEL: addcrs
5858
define void @addcrs(i256 %rs1) nounwind {
5959
%valptr = alloca i256
60-
; CHECK: add @val[0], r1, stack-[1]
60+
; CHECK: add code[@val], r1, stack-[1]
6161
%val = load i256, i256 addrspace(4)* @val
6262
%res = add i256 %rs1, %val
6363
store i256 %res, i256* %valptr

0 commit comments

Comments
 (0)