get branches to block working (#20996)

* carith() function in exe1.c tests

* get branches to blocks working
This commit is contained in:
Walter Bright 2025-03-15 01:27:52 -07:00 committed by GitHub
parent 2408ac30e9
commit 142d509af2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 34 additions and 12 deletions

View file

@ -292,7 +292,7 @@ void gen_loadcse(ref CodeBuilder cdb, tym_t tym, reg_t reg, size_t slot)
void genBranch(ref CodeBuilder cdb, COND cond, FL fltarg, block* targ)
{
code cs;
cs.Iop = ((0x54 << 24) | cond);
cs.Iop = INSTR.b_cond(0, cond); // offset is 0 for now, fix in codout()
cs.Iflags = 0;
cs.IFL1 = fltarg; // FL.block (or FL.code)
cs.IEV1.Vblock = targ; // target block (or code)
@ -741,6 +741,7 @@ Lret:
@trusted
int branch(block* bl,int flag)
{
//printf("branch() flag: %d\n", flag);
int bytesaved;
code* c,cn,ct;
targ_size_t offset,disp;
@ -1491,6 +1492,7 @@ printf("offset: %lld localsize: %lld REGSIZE*2: %d\n", offset, localsize, REGSIZ
case FL.func:
case FL.code:
case FL.unde:
case FL.block:
break;
default:
@ -1523,7 +1525,8 @@ void jmpaddr(code* c)
while (c)
{
const op = c.Iop;
if (isBranch(op)) // or CALL?
//printf("%08X ", c.Iop); disassemble(c.Iop);
if (isBranch(op) && c.IFL2 == FL.code) // or CALL?
{
ci = code_next(c);
ctarg = c.IEV1.Vcode; /* target code */
@ -1678,9 +1681,14 @@ uint codout(int seg, code* c, Barray!ubyte* disasmBuf, ref targ_size_t framehand
if (ggen.available() < 4)
ggen.flush();
//printf("op: %08x\n", op);
//if ((op & 0xFC00_0000) == 0x9400_0000) // BL <label>
if (Symbol* s = c.IEV1.Vsym)
if (c.IFL1 == FL.block) // branch to a block - compute offset
{
ggen.flush();
int ad = cast(int)(c.IEV1.Vblock.Boffset - ggen.offset);
op |= ((ad >> 2) & 0x7FFFF) << 5; // imm19 in opcode
ggen.gen32(op);
}
else if (Symbol* s = c.IEV1.Vsym)
{
switch (s.Sclass)
{

View file

@ -608,7 +608,7 @@ void cdmulass(ref CGstate cg, ref CodeBuilder cdb,elem* e,ref regm_t pretregs)
regm_t earegm = mask(cs.base) | mask(cs.index);
regm_t retregs;
reg_t reg;
if (cs.reg)
if (cs.reg != NOREG)
{
reg = cs.reg;
retregs = mask(reg);
@ -759,7 +759,7 @@ void cdshass(ref CGstate cg, ref CodeBuilder cdb,elem* e,ref regm_t pretregs)
regm_t earegm = mask(cs.base) | mask(cs.index);
regm_t retregs;
reg_t Rshiftee;
if (cs.reg)
if (cs.reg != NOREG)
{
Rshiftee = cs.reg;
retregs = mask(Rshiftee);
@ -793,11 +793,12 @@ void cdshass(ref CGstate cg, ref CodeBuilder cdb,elem* e,ref regm_t pretregs)
uint opcode;
switch (e.Eoper)
{
case OPshl: opcode = 0x8; break;
case OPshr: opcode = 0x9; break;
case OPashr: opcode = 0xA; break;
case OPshlass: opcode = 0x8; break;
case OPshrass: opcode = 0x9; break;
case OPashrass: opcode = 0xA; break;
//case OPror: opcode = 0xB; break;
default:
elem_print(e);
assert(0);
}

View file

@ -264,7 +264,15 @@ struct INSTR
/* https://www.scs.stanford.edu/~zyedidia/arm64/encodingindex.html#control */
/* Conditional branch (immediate)
* Miscellaneous branch (immediate)
* B.<cond> <label> https://www.scs.stanford.edu/~zyedidia/arm64/b_cond.html
*/
static uint b_cond(int imm19, uint cond) { return (0x54 << 24) | ((imm19 & 0x7FFFF) << 5) | cond; }
/* BC.<cond> <label> https://www.scs.stanford.edu/~zyedidia/arm64/bc_cond.html
*/
static uint bc_cond(int imm19, uint cond) { return (0x54 << 24) | (1 << 4) | ((imm19 & 0x7FFFF) << 5) | cond; }
/* Miscellaneous branch (immediate)
*/
/* Exception generation http://www.scs.stanford.edu/~zyedidia/arm64/encodingindex.html#exception

View file

@ -886,6 +886,8 @@ private code* callFinallyBlock(block* bf, regm_t retregs)
@trusted
void outblkexitcode(ref CodeBuilder cdb, block* bl, ref int anyspill, const(FL)* sflsave, Symbol** retsym, const regm_t mfuncregsave)
{
//printf("outblkexitcode()\n");
bool AArch64 = cgstate.AArch64;
CodeBuilder cdb2; cdb2.ctor();
elem* e = bl.Belem;
block* nextb;
@ -923,6 +925,9 @@ void outblkexitcode(ref CodeBuilder cdb, block* bl, ref int anyspill, const(FL)*
if (nextb != bl.Bnext)
{
assert(!(bl.Bflags & BFL.epilog));
if (AArch64)
dmd.backend.arm.cod3.genBranch(cdb,COND.al,FL.block,nextb);
else
genjmp(cdb,JMP,FL.block,nextb);
}
break;