Skip to content

Commit ecca304

Browse files
authored
add thunk generation (dlang#21439)
1 parent c8ced19 commit ecca304

File tree

4 files changed

+111
-3
lines changed

4 files changed

+111
-3
lines changed

compiler/src/dmd/backend/arm/cod3.d

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -859,7 +859,97 @@ Lret:
859859

860860
// cod3_spoff
861861
// gen_spill_reg
862-
// cod3_thunk
862+
863+
/****************************
864+
* Generate code for, and output a thunk.
865+
* Params:
866+
* sthunk = Symbol of thunk
867+
* sfunc = Symbol of thunk's target function
868+
* thisty = Type of this pointer
869+
* p = ESP parameter offset to this pointer (0 for D)
870+
* d = offset to add to 'this' pointer
871+
* d2 = offset from 'this' to vptr (0 for D)
872+
* i = offset into vtbl[] (-1 for D)
873+
*/
874+
@trusted
875+
void cod3_thunk(Symbol* sthunk,Symbol* sfunc,uint p,tym_t thisty,
876+
uint d,int i,uint d2)
877+
{
878+
assert(p == 0 && i == -1 && d2 == 0); // for single inheritance
879+
880+
targ_size_t thunkoffset;
881+
882+
int seg = sthunk.Sseg;
883+
cod3_align(seg);
884+
885+
// Skip over return address
886+
tym_t thunkty = tybasic(sthunk.ty());
887+
888+
CodeBuilder cdb; cdb.ctor();
889+
890+
/*
891+
Generate:
892+
ADD p[ESP],d
893+
For direct call:
894+
JMP sfunc
895+
For virtual call:
896+
MOV EAX, p[ESP] EAX = this
897+
MOV EAX, d2[EAX] EAX = this.vptr
898+
JMP i[EAX] jump to virtual function
899+
*/
900+
if (config.flags3 & CFG3ibt)
901+
//cdb.gen1(I32 ? ENDBR32 : ENDBR64);
902+
assert(0); // TODO AArch64
903+
904+
uint op = 0; // ADD
905+
if (cast(int)d < 0)
906+
{
907+
d = -d;
908+
op = 1; // switch from ADD to SUB
909+
}
910+
if (thunkty == TYmfunc || thunkty == TYjfunc || thunkty == TYnfunc)
911+
{
912+
uint sh = 0;
913+
reg_t r0 = 0;
914+
cdb.gen1(INSTR.addsub_imm(1,op,0,sh,d,r0,r0)); // ADD/SUB r0,r0,d
915+
}
916+
else
917+
{
918+
assert(0);
919+
}
920+
921+
if (0 && config.flags3 & CFG3pic) // TODO AArch64
922+
{
923+
localgot = null; // no local variables
924+
CodeBuilder cdbgot; cdbgot.ctor();
925+
load_localgot(cdbgot); // load GOT in EBX
926+
code* c1 = cdbgot.finish();
927+
if (c1)
928+
{
929+
assignaddrc(c1);
930+
cdb.append(c1);
931+
}
932+
}
933+
cdb.gencs1(INSTR.bl(0),0,FL.func,sfunc); // BL sfunc // http://www.scs.stanford.edu/~zyedidia/arm64/bl.html
934+
cdb.last().Iflags |= (CFselfrel | CFoff);
935+
936+
thunkoffset = Offset(seg);
937+
code* c = cdb.finish();
938+
//pinholeopt(c,null);
939+
targ_size_t framehandleroffset;
940+
codout(seg,c,null,framehandleroffset);
941+
code_free(c);
942+
943+
sthunk.Soffset = thunkoffset;
944+
sthunk.Ssize = Offset(seg) - thunkoffset; // size of thunk
945+
sthunk.Sseg = seg;
946+
if (config.exe & EX_posix ||
947+
config.objfmt == OBJ_MSCOFF)
948+
{
949+
objmod.pubdef(seg,sthunk,sthunk.Soffset);
950+
}
951+
}
952+
863953
// makeitextern
864954

865955
/*******************************

compiler/src/dmd/backend/arm/disasmarm.d

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1184,6 +1184,7 @@ void disassemble(uint c) @trusted
11841184

11851185
p1 = op ? "bl" : "b";
11861186
p2 = wordtostring(imm26 * 4);
1187+
url2 = op ? "bl" : "b_uncond";
11871188
}
11881189
else if (field(ins, 30, 25) == 0x1A) // http://www.scs.stanford.edu/~zyedidia/arm64/encodingindex.html#compbranch
11891190
{

compiler/src/dmd/backend/arm/instr.d

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -348,15 +348,26 @@ struct INSTR
348348
return (0x6B << 25) | (opc << 21) | (op2 << 16) | (op3 << 10) | (Rn << 5) | op4;
349349
}
350350

351-
/* Unconditional branch (immediate)
352-
* B/BL
351+
/* Unconditional branch (immediate) */
352+
353+
/* B/BL
353354
* https://www.scs.stanford.edu/~zyedidia/arm64/encodingindex.html#branch_imm
354355
*/
355356
static uint branch_imm(uint op, uint imm26)
356357
{
357358
return (op << 31) | (5 << 26) | imm26;
358359
}
359360

361+
/* B <label>
362+
* https://www.scs.stanford.edu/~zyedidia/arm64/b_uncond.html
363+
*/
364+
static uint b_uncond(uint imm26) { return branch_imm(0, imm26); }
365+
366+
/* BL <label> hint that it's a subroutine call
367+
* https://www.scs.stanford.edu/~zyedidia/arm64/bl.html
368+
*/
369+
static uint bl(uint imm26) { return branch_imm(1, imm26); }
370+
360371
/* RET Xn
361372
* https://www.scs.stanford.edu/~zyedidia/arm64/ret.html
362373
*/

compiler/src/dmd/backend/x86/cod3.d

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4976,6 +4976,12 @@ void gen_spill_reg(ref CodeBuilder cdb, Symbol* s, bool toreg)
49764976
void cod3_thunk(Symbol* sthunk,Symbol* sfunc,uint p,tym_t thisty,
49774977
uint d,int i,uint d2)
49784978
{
4979+
if (cgstate.AArch64)
4980+
{
4981+
import dmd.backend.arm.cod3 : cod3_thunk;
4982+
return cod3_thunk(sthunk, sfunc, p, thisty, d, i, d2);
4983+
}
4984+
49794985
targ_size_t thunkoffset;
49804986

49814987
int seg = sthunk.Sseg;

0 commit comments

Comments
 (0)