Add support for jumps to local labels.

Currently limited to 16-bits ONLY.

Allows code like:

|1:
| ...
| j <1
This commit is contained in:
Michael Munday 2016-12-05 17:21:49 -05:00
parent 410bdb8182
commit 73ad6dc77d
3 changed files with 38 additions and 10 deletions

View File

@ -8,6 +8,7 @@
// DynASM directives. // DynASM directives.
|.arch s390x |.arch s390x
|.actionlist actions |.actionlist actions
|.globals lab_
static void add(dasm_State *state) static void add(dasm_State *state)
{ {
@ -61,6 +62,20 @@ static void rxy(dasm_State *state)
| br r14 | br r14
} }
static void lab(dasm_State *state)
{
dasm_State **Dst = &state;
// r1 = 0; do { r2 += r2; r1 += 1; } while(r1 < r3);
| la r1, 0(r0)
|1:
| agr r2, r2
| la r1, 1(r1)
| cgr r1, r3
| jl <1
| br r14
}
typedef struct { typedef struct {
int64_t arg1; int64_t arg1;
int64_t arg2; int64_t arg2;
@ -74,7 +89,8 @@ test_table test[] = {
{10, 5, sub, 5, "sub"}, {10, 5, sub, 5, "sub"},
{ 2, 3, mul, 6, "mul"}, { 2, 3, mul, 6, "mul"},
{ 5, 7, rx, 12298, "rx"}, { 5, 7, rx, 12298, "rx"},
{ 5, 7, rxy, 10, "rxy"} { 5, 7, rxy, 10, "rxy"},
{ 2, 4, lab, 32, "lab"}
}; };
static void *jitcode(dasm_State **state, size_t *size) static void *jitcode(dasm_State **state, size_t *size)
@ -93,9 +109,10 @@ static void *jitcode(dasm_State **state, size_t *size)
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
dasm_State *state; dasm_State *state;
for(int i = 0; i < sizeof(test)/sizeof(test[0]); i++) { for(int i = 0; i < sizeof(test)/sizeof(test[0]); i++) {
dasm_init(&state, 1); dasm_init(&state, 1);
void* labels[lab__MAX];
dasm_setupglobal(&state, labels, lab__MAX);
dasm_setup(&state, actions); dasm_setup(&state, actions);
test[i].fn(state); test[i].fn(state);
size_t size; size_t size;

View File

@ -219,7 +219,7 @@ void dasm_put(Dst_DECL, int start, ...)
b[pos++] = ofs; b[pos++] = ofs;
break; break;
case DASM_REL_LG: case DASM_REL_LG:
n = (ins & 2047) - 10; n = *p++ - 10;
pl = D->lglabels + n; pl = D->lglabels + n;
/* Bkwd rel or global. */ /* Bkwd rel or global. */
if (n >= 0) { if (n >= 0) {
@ -247,7 +247,7 @@ void dasm_put(Dst_DECL, int start, ...)
pos++; pos++;
break; break;
case DASM_LABEL_LG: case DASM_LABEL_LG:
pl = D->lglabels + (ins & 2047) - 10; pl = D->lglabels + *p++ - 10;
CKPL(lg, LG); CKPL(lg, LG);
goto putlabel; goto putlabel;
case DASM_LABEL_PC: case DASM_LABEL_PC:
@ -262,6 +262,7 @@ void dasm_put(Dst_DECL, int start, ...)
} }
*pl = -pos; /* Label exists now. */ *pl = -pos; /* Label exists now. */
b[pos++] = ofs; /* Store pass1 offset estimate. */ b[pos++] = ofs; /* Store pass1 offset estimate. */
ofs += 2;
break; break;
case DASM_IMM16: case DASM_IMM16:
CK(((short)n) == n, RANGE_I); /* TODO: unsigned immediates? */ CK(((short)n) == n, RANGE_I); /* TODO: unsigned immediates? */
@ -348,10 +349,12 @@ int dasm_link(Dst_DECL, size_t * szp)
break; break;
case DASM_REL_LG: case DASM_REL_LG:
case DASM_REL_PC: case DASM_REL_PC:
p++;
pos++; pos++;
break; break;
case DASM_LABEL_LG: case DASM_LABEL_LG:
case DASM_LABEL_PC: case DASM_LABEL_PC:
p++;
b[pos++] += ofs; b[pos++] += ofs;
break; break;
case DASM_IMM16: case DASM_IMM16:
@ -421,13 +424,11 @@ int dasm_encode(Dst_DECL, void *buffer)
CK(n >= 0, UNDEF_PC); CK(n >= 0, UNDEF_PC);
n = *DASM_POS2PTR(D, n) - (int)((char *)cp - base); n = *DASM_POS2PTR(D, n) - (int)((char *)cp - base);
patchrel: patchrel:
CK((n & 3) == 0 && *cp++ = n/2; /* TODO: only 16-bit relative jump currently works. */
(((n + 4) + ((ins & 2048) ? 0x00008000 : 0x02000000)) >> p++; /* skip argument */
((ins & 2048) ? 16 : 26)) == 0, RANGE_REL);
cp[-1] |= ((n + 4) & ((ins & 2048) ? 0x0000fffc : 0x03fffffc));
break; break;
case DASM_LABEL_LG: case DASM_LABEL_LG:
ins &= 2047; ins = *p++;
if (ins >= 20) if (ins >= 20)
D->globals[ins - 10] = (void *)(base + n); D->globals[ins - 10] = (void *)(base + n);
break; break;

View File

@ -1057,6 +1057,14 @@ local function parse_template(params, template, nparams, pos)
op2 = op2 + band(shr(d, 4), 0xff00) op2 = op2 + band(shr(d, 4), 0xff00)
wputhw(op0); wputhw(op1); wputhw(op2) wputhw(op0); wputhw(op1); wputhw(op2)
if a then a() end -- a() emits action. if a then a() end -- a() emits action.
elseif p == "w" then
local mode, n, s = parse_label(params[1])
wputhw(op1)
waction("REL_"..mode, n, s)
elseif p == "x" then
local mode, n, s = parse_label(params[1])
wputhw(op0)
waction("REL_"..mode, n, s)
elseif p == "y" then elseif p == "y" then
local d, x, b, a = parse_mem_bx(params[1]) local d, x, b, a = parse_mem_bx(params[1])
op1 = op1 + x op1 = op1 + x
@ -1066,6 +1074,8 @@ local function parse_template(params, template, nparams, pos)
elseif p == "z" then elseif p == "z" then
op2 = op2 + parse_gpr(params[1]) op2 = op2 + parse_gpr(params[1])
wputhw(op2) wputhw(op2)
else
werror("unrecognized encoding")
end end
end end