From eb45e104be216adb76eaacfeea78935ee5165e0b Mon Sep 17 00:00:00 2001 From: ketmar Date: Thu, 23 Jul 2020 07:29:42 +0000 Subject: [PATCH] urasm: added "XBRANCH" forth word flag; it will use `USE_REL_BRANCH` EQU label to choose branch type FossilOrigin-Name: 9dfecbff2d2700e11aeb65b32831f611c4619d8a0ef984d0bb56e23748e09deb --- src/urasm.c | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/src/urasm.c b/src/urasm.c index 5bfde7f..a46f0cf 100644 --- a/src/urasm.c +++ b/src/urasm.c @@ -3558,7 +3558,7 @@ typedef struct ForthWordT { char *name; // uppercased uint16_t nfa; uint16_t cfa; - int isbranch; // <0: wants relative addr; >0: wants absolute addr + int isbranch; // -1: wants relative addr; 1: wants absolute addr; -666: check `USE_REL_BRANCH` struct ForthWordT *next; } ForthWord; @@ -3722,6 +3722,17 @@ static int piForthUser (void) { } +static void forthParseBranchFlag (ForthWord *nw) { + const char *wname = forthGetWord(); + if (wname) { + if (strcasecmp(wname, "RBRANCH") == 0) nw->isbranch = -1; + else if (strcasecmp(wname, "ABRANCH") == 0) nw->isbranch = 1; + else if (strcasecmp(wname, "XBRANCH") == 0) nw->isbranch = -666; + else fatal("end of line expected"); + } +} + + static int piForthCodeWord (void) { if (asmMode != AMODE_NORMAL) fatal("invalid forth define"); asmMode = AMODE_FCODE; @@ -3730,12 +3741,7 @@ static int piForthCodeWord (void) { ForthWord *nw = forthWordHead(wname, 0); // cfa emitWord((disp+2)&0xffffU); - wname = forthGetWord(); - if (wname) { - if (strcasecmp(wname, "RBRANCH") == 0) nw->isbranch = -1; - else if (strcasecmp(wname, "ABRANCH") == 0) nw->isbranch = 1; - else fatal("end of line expected"); - } + forthParseBranchFlag(nw); checkOperatorEnd(); //fprintf(stderr, "FORTH CODE WORD: '%s'\n", nw->name); forthCurrWord = nw->name; @@ -3770,12 +3776,7 @@ static int piForthWord (void) { free(fwn); // cfa forthEmitLabel("_doforth"); - wname = forthGetWord(); - if (wname) { - if (strcasecmp(wname, "RBRANCH") == 0) nw->isbranch = -1; - else if (strcasecmp(wname, "ABRANCH") == 0) nw->isbranch = 1; - else fatal("end of line expected"); - } + forthParseBranchFlag(nw); checkOperatorEnd(); //fprintf(stderr, "FORTH WORD: '%s'\n", nw->name); forthCurrWord = nw->name; @@ -4101,7 +4102,13 @@ static void processForthWordLine (void) { if (!lbl) fatal("unknown label in forth code: '%s'", wname); if (!lbl->known) fatal("undefined label '%s'", lbl->name); if (lbl->value < 0 || lbl->value > 65535) fatal("invalid jump label in forth code: '%s' (%d)", wname, lbl->value); - if (fw->isbranch < 0) { + int brt = fw->isbranch; + if (brt == -666) { + UrLabelInfo *brtl = urFindLabel("USE_REL_BRANCH"); + if (!brtl || !brtl->known || brtl->type < 0) fatal("forth XBRANCH requires defined `USE_REL_BRANCH`"); + brt = (brtl->value ? -1 : 1); + } + if (brt < 0) { // relative int v = lbl->value-(int)disp; if (v < -32767 || v > 32767) fatal("forth jump too far"); -- 2.11.4.GIT