Merge pull request #279 from Daniel-Cortez/emit-patch1
Another bunch of fixes/improvements for 'emit'
This commit is contained in:
commit
f52bed7043
@ -398,14 +398,16 @@ typedef struct s_valuepair {
|
|||||||
#define tLABEL 337
|
#define tLABEL 337
|
||||||
#define tSTRING 338
|
#define tSTRING 338
|
||||||
/* argument types for emit/__emit */
|
/* argument types for emit/__emit */
|
||||||
#define teNUMERIC 339 /* integer/rational number */
|
#define teANY 339 /* any value */
|
||||||
#define teDATA 340 /* data (variable name or address) */
|
#define teNUMERIC 340 /* integer/rational number */
|
||||||
#define teLOCAL 341 /* local variable (name or offset) */
|
#define teDATA 341 /* data (variable name or address) */
|
||||||
#define teFUNCTN 342 /* Pawn function */
|
#define teLOCAL 342 /* local variable (name or offset) */
|
||||||
#define teNATIVE 343 /* native function */
|
#define teFUNCTN 343 /* Pawn function */
|
||||||
|
#define teNATIVE 344 /* native function */
|
||||||
|
#define teNONNEG 345 /* nonnegative integer */
|
||||||
/* for assigment to "lastst" only (see SC1.C) */
|
/* for assigment to "lastst" only (see SC1.C) */
|
||||||
#define tEXPR 344
|
#define tEXPR 346
|
||||||
#define tENDLESS 345 /* endless loop */
|
#define tENDLESS 347 /* endless loop */
|
||||||
|
|
||||||
/* (reversed) evaluation of staging buffer */
|
/* (reversed) evaluation of staging buffer */
|
||||||
#define sSTARTREORDER 0x01
|
#define sSTARTREORDER 0x01
|
||||||
@ -475,6 +477,17 @@ typedef enum s_optmark {
|
|||||||
|
|
||||||
#define MAX_INSTR_LEN 30
|
#define MAX_INSTR_LEN 30
|
||||||
|
|
||||||
|
#define eotNUMBER 0
|
||||||
|
#define eotFUNCTION 1
|
||||||
|
#define eotLABEL 2
|
||||||
|
typedef struct s_emit_outval {
|
||||||
|
int type;
|
||||||
|
union {
|
||||||
|
ucell ucell;
|
||||||
|
const char *string;
|
||||||
|
} value;
|
||||||
|
} emit_outval;
|
||||||
|
|
||||||
/* interface functions */
|
/* interface functions */
|
||||||
#if defined __cplusplus
|
#if defined __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -699,7 +712,7 @@ SC_FUNC void dec(value *lval);
|
|||||||
SC_FUNC void jmp_ne0(int number);
|
SC_FUNC void jmp_ne0(int number);
|
||||||
SC_FUNC void jmp_eq0(int number);
|
SC_FUNC void jmp_eq0(int number);
|
||||||
SC_FUNC void outval(cell val,int newline);
|
SC_FUNC void outval(cell val,int newline);
|
||||||
SC_FUNC void outinstr(const char *name,ucell args[],int numargs);
|
SC_FUNC void outinstr(const char *name,emit_outval params[],int numparams);
|
||||||
|
|
||||||
/* function prototypes in SC5.C */
|
/* function prototypes in SC5.C */
|
||||||
SC_FUNC int error(int number,...);
|
SC_FUNC int error(int number,...);
|
||||||
|
@ -137,7 +137,6 @@ static void dostate(void);
|
|||||||
static void addwhile(int *ptr);
|
static void addwhile(int *ptr);
|
||||||
static void delwhile(void);
|
static void delwhile(void);
|
||||||
static int *readwhile(void);
|
static int *readwhile(void);
|
||||||
static void doemit(void);
|
|
||||||
|
|
||||||
typedef void (SC_FASTCALL *OPCODE_PROC)(char *name);
|
typedef void (SC_FASTCALL *OPCODE_PROC)(char *name);
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -5290,7 +5289,6 @@ static void statement(int *lastindent,int allow_decl)
|
|||||||
extern char *sc_tokens[];
|
extern char *sc_tokens[];
|
||||||
const unsigned char *bck_lptr=lptr-strlen(sc_tokens[tok-tFIRST]);
|
const unsigned char *bck_lptr=lptr-strlen(sc_tokens[tok-tFIRST]);
|
||||||
if (matchtoken('{')) {
|
if (matchtoken('{')) {
|
||||||
lexpush();
|
|
||||||
emit_flags |= efBLOCK;
|
emit_flags |= efBLOCK;
|
||||||
lastst=tEMIT;
|
lastst=tEMIT;
|
||||||
break;
|
break;
|
||||||
@ -5299,7 +5297,7 @@ static void statement(int *lastindent,int allow_decl)
|
|||||||
lexclr(FALSE);
|
lexclr(FALSE);
|
||||||
tok=lex(&val,&st);
|
tok=lex(&val,&st);
|
||||||
} /* case */
|
} /* case */
|
||||||
/* drop through */
|
/* fallthrough */
|
||||||
default: /* non-empty expression */
|
default: /* non-empty expression */
|
||||||
sc_allowproccall=optproccall;
|
sc_allowproccall=optproccall;
|
||||||
lexpush(); /* analyze token later */
|
lexpush(); /* analyze token later */
|
||||||
@ -5957,23 +5955,26 @@ static void SC_FASTCALL emit_invalid_token(int expected_token,int found_token)
|
|||||||
} /* if */
|
} /* if */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SC_FASTCALL emit_param_any(ucell *p)
|
static int SC_FASTCALL emit_param_any_internal(emit_outval *p,int expected_tok,
|
||||||
|
int allow_nonint,int allow_expr)
|
||||||
{
|
{
|
||||||
char *str;
|
char *str;
|
||||||
cell val,cidx;
|
cell val,cidx;
|
||||||
symbol *sym;
|
symbol *sym;
|
||||||
extern char *sc_tokens[];
|
int tok,negate,ident,index;
|
||||||
int tok,neg,ident,index;
|
|
||||||
|
|
||||||
neg=FALSE;
|
negate=FALSE;
|
||||||
|
p->type=eotNUMBER;
|
||||||
fetchtok:
|
fetchtok:
|
||||||
tok=lex(&val,&str);
|
tok=lex(&val,&str);
|
||||||
switch (tok) {
|
switch (tok) {
|
||||||
case tNUMBER:
|
case tNUMBER:
|
||||||
*p=(neg!=FALSE) ? -val : val;
|
p->value.ucell=(ucell)(negate ? -val : val);
|
||||||
break;
|
break;
|
||||||
case tRATIONAL:
|
case tRATIONAL:
|
||||||
*p=(neg!=FALSE) ? (val|((cell)1 << (PAWN_CELL_SIZE-1))) : val;
|
if (!allow_nonint)
|
||||||
|
goto invalid_token;
|
||||||
|
p->value.ucell=(ucell)(negate ? (val|((cell)1 << (PAWN_CELL_SIZE-1))) : val);
|
||||||
break;
|
break;
|
||||||
case tSYMBOL:
|
case tSYMBOL:
|
||||||
sym=findloc(str);
|
sym=findloc(str);
|
||||||
@ -5981,67 +5982,158 @@ fetchtok:
|
|||||||
sym=findglb(str,sSTATEVAR);
|
sym=findglb(str,sSTATEVAR);
|
||||||
if (sym==NULL || (sym->ident!=iFUNCTN && sym->ident!=iREFFUNC && (sym->usage & uDEFINE)==0)) {
|
if (sym==NULL || (sym->ident!=iFUNCTN && sym->ident!=iREFFUNC && (sym->usage & uDEFINE)==0)) {
|
||||||
error(17,str); /* undefined symbol */
|
error(17,str); /* undefined symbol */
|
||||||
break;
|
return FALSE;
|
||||||
} /* if */
|
} /* if */
|
||||||
if (sym->ident==iLABEL) {
|
if (sym->ident==iLABEL) {
|
||||||
|
sym->usage|=uREAD;
|
||||||
|
if (negate)
|
||||||
|
goto invalid_token_neg;
|
||||||
|
if (!allow_nonint) {
|
||||||
tok=tLABEL;
|
tok=tLABEL;
|
||||||
goto invalid_token;
|
goto invalid_token;
|
||||||
} /* if */
|
} /* if */
|
||||||
if (sym->ident==iFUNCTN || sym->ident==iREFFUNC) {
|
p->type=eotLABEL;
|
||||||
|
p->value.ucell=(ucell)sym->addr;
|
||||||
|
} else if (sym->ident==iFUNCTN || sym->ident==iREFFUNC) {
|
||||||
|
markusage(sym,uREAD);
|
||||||
|
if (negate)
|
||||||
|
goto invalid_token_neg;
|
||||||
|
if (!allow_nonint) {
|
||||||
|
tok=(sym->usage & uNATIVE) ? teNATIVE : teFUNCTN;
|
||||||
|
goto invalid_token;
|
||||||
|
} /* if */
|
||||||
if ((sym->usage & uNATIVE)!=0 && (sym->usage & uREAD)==0 && sym->addr>=0)
|
if ((sym->usage & uNATIVE)!=0 && (sym->usage & uREAD)==0 && sym->addr>=0)
|
||||||
sym->addr=ntv_funcid++;
|
sym->addr=ntv_funcid++;
|
||||||
markusage(sym,uREAD);
|
p->type=eotFUNCTION;
|
||||||
|
p->value.string=str;
|
||||||
} else {
|
} else {
|
||||||
markusage(sym,uREAD | uWRITTEN);
|
markusage(sym,uREAD | uWRITTEN);
|
||||||
|
if (!allow_nonint && sym->ident!=iCONSTEXPR) {
|
||||||
|
tok=(sym->vclass==sLOCAL) ? teLOCAL : teDATA;
|
||||||
|
goto invalid_token;
|
||||||
|
} /* if */
|
||||||
|
p->value.ucell=(ucell)(negate ? -sym->addr : sym->addr);
|
||||||
} /* if */
|
} /* if */
|
||||||
*p=(neg!=FALSE) ? -sym->addr : sym->addr;
|
|
||||||
break;
|
break;
|
||||||
case '(':
|
case '(':
|
||||||
|
if (!allow_expr)
|
||||||
|
goto invalid_token;
|
||||||
if ((emit_flags & efEXPR)==0)
|
if ((emit_flags & efEXPR)==0)
|
||||||
stgset(TRUE);
|
stgset(TRUE);
|
||||||
stgget(&index,&cidx);
|
stgget(&index,&cidx);
|
||||||
errorset(sEXPRMARK,0);
|
errorset(sEXPRMARK,0);
|
||||||
ident=expression(&val,NULL,NULL,FALSE);
|
ident=expression(&val,NULL,NULL,FALSE);
|
||||||
if (ident!=iCONSTEXPR)
|
|
||||||
error(8); /* must be constant expression */
|
|
||||||
errorset(sEXPRRELEASE,0);
|
errorset(sEXPRRELEASE,0);
|
||||||
stgdel(index,cidx);
|
stgdel(index,cidx);
|
||||||
if ((emit_flags & efEXPR)==0)
|
if ((emit_flags & efEXPR)==0)
|
||||||
stgset(FALSE);
|
stgset(FALSE);
|
||||||
needtoken(')');
|
needtoken(')');
|
||||||
*p=(neg!=FALSE) ? -val : val;
|
p->value.ucell=(ucell)(negate ? -val : val);
|
||||||
|
if (ident!=iCONSTEXPR) {
|
||||||
|
error(8); /* must be constant expression */
|
||||||
|
return FALSE;
|
||||||
|
} /* if */
|
||||||
|
break;
|
||||||
|
case ':':
|
||||||
|
tok=lex(&val,&str);
|
||||||
|
if (tok!=tSYMBOL) {
|
||||||
|
emit_invalid_token(tSYMBOL,tok);
|
||||||
|
return FALSE;
|
||||||
|
} /* if */
|
||||||
|
sym=fetchlab(str);
|
||||||
|
sym->usage|=uREAD;
|
||||||
|
p->type=eotLABEL;
|
||||||
|
p->value.ucell=(ucell)sym->addr;
|
||||||
break;
|
break;
|
||||||
case '-':
|
case '-':
|
||||||
if (neg==FALSE) {
|
if (!negate) {
|
||||||
neg=TRUE;
|
negate=TRUE;
|
||||||
goto fetchtok;
|
goto fetchtok;
|
||||||
} else {
|
} else {
|
||||||
char ival[sNAMEMAX+2]="-";
|
extern char *sc_tokens[];
|
||||||
strcpy(ival+1,str);
|
char ival[sNAMEMAX+2];
|
||||||
error(1,sc_tokens[tSYMBOL-tFIRST],ival);
|
invalid_token_neg:
|
||||||
break;
|
sprintf(ival,"-%s",str);
|
||||||
|
error(1,sc_tokens[expected_tok-tFIRST],ival);
|
||||||
|
return FALSE;
|
||||||
} /* if */
|
} /* if */
|
||||||
default:
|
default:
|
||||||
invalid_token:
|
invalid_token:
|
||||||
emit_invalid_token(teNUMERIC,tok);
|
emit_invalid_token(expected_tok,tok);
|
||||||
|
return FALSE;
|
||||||
} /* switch */
|
} /* switch */
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SC_FASTCALL emit_param_data(ucell *p)
|
static void SC_FASTCALL emit_param_any(emit_outval *p)
|
||||||
|
{
|
||||||
|
emit_param_any_internal(p,teANY,TRUE,TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SC_FASTCALL emit_param_integer(emit_outval *p)
|
||||||
|
{
|
||||||
|
emit_param_any_internal(p,tNUMBER,FALSE,TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SC_FASTCALL emit_param_index(emit_outval *p,int isrange,const cell *valid_values,int numvalues)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
cell val;
|
||||||
|
|
||||||
|
assert(isrange ? (numvalues==2) : (numvalues>0));
|
||||||
|
if (!emit_param_any_internal(p,tNUMBER,FALSE,FALSE))
|
||||||
|
return;
|
||||||
|
val=(cell)p->value.ucell;
|
||||||
|
if (isrange) {
|
||||||
|
if (valid_values[0]<=val && val<=valid_values[1])
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
for (i=0; i<numvalues; i++)
|
||||||
|
if (val==valid_values[i])
|
||||||
|
return;
|
||||||
|
} /* if */
|
||||||
|
error(50); /* invalid range */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SC_FASTCALL emit_param_nonneg(emit_outval *p)
|
||||||
|
{
|
||||||
|
if (!emit_param_any_internal(p,teNONNEG,FALSE,TRUE))
|
||||||
|
return;
|
||||||
|
if ((cell)p->value.ucell<(cell)0) {
|
||||||
|
extern char *sc_tokens[];
|
||||||
|
#if PAWN_CELL_SIZE==16
|
||||||
|
char ival[7];
|
||||||
|
sprintf(ival,"%ld",(long)p->value.ucell);
|
||||||
|
#elif PAWN_CELL_SIZE==32
|
||||||
|
char ival[12];
|
||||||
|
sprintf(ival,"%ld",(long)p->value.ucell);
|
||||||
|
#elif PAWN_CELL_SIZE==64
|
||||||
|
char ival[21];
|
||||||
|
sprintf(ival,"%lld",(long long)p->value.ucell);
|
||||||
|
#else
|
||||||
|
#error Unsupported cell size
|
||||||
|
#endif
|
||||||
|
error(1,sc_tokens[teNONNEG-tFIRST],ival);
|
||||||
|
} /* if */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SC_FASTCALL emit_param_data(emit_outval *p)
|
||||||
{
|
{
|
||||||
cell val;
|
cell val;
|
||||||
char *str;
|
char *str;
|
||||||
symbol *sym;
|
symbol *sym;
|
||||||
int tok;
|
int tok;
|
||||||
|
|
||||||
|
p->type=eotNUMBER;
|
||||||
tok=lex(&val,&str);
|
tok=lex(&val,&str);
|
||||||
switch (tok) {
|
switch (tok) {
|
||||||
case tNUMBER:
|
case tNUMBER:
|
||||||
*p=val;
|
p->value.ucell=(ucell)val;
|
||||||
break;
|
break;
|
||||||
case tSYMBOL:
|
case tSYMBOL:
|
||||||
sym=findloc(str);
|
sym=findloc(str);
|
||||||
if (sym!=NULL) {
|
if (sym!=NULL) {
|
||||||
|
markusage(sym,uREAD | uWRITTEN);
|
||||||
if (sym->ident==iLABEL) {
|
if (sym->ident==iLABEL) {
|
||||||
tok=tLABEL;
|
tok=tLABEL;
|
||||||
goto invalid_token;
|
goto invalid_token;
|
||||||
@ -6056,13 +6148,13 @@ static void SC_FASTCALL emit_param_data(ucell *p)
|
|||||||
error(17,str); /* undefined symbol */
|
error(17,str); /* undefined symbol */
|
||||||
break;
|
break;
|
||||||
} /* if */
|
} /* if */
|
||||||
|
markusage(sym,uREAD | uWRITTEN);
|
||||||
if (sym->ident==iFUNCTN || sym->ident==iREFFUNC) {
|
if (sym->ident==iFUNCTN || sym->ident==iREFFUNC) {
|
||||||
tok=((sym->usage & uNATIVE)!=0) ? teNATIVE : teFUNCTN;
|
tok=((sym->usage & uNATIVE)!=0) ? teNATIVE : teFUNCTN;
|
||||||
goto invalid_token;
|
goto invalid_token;
|
||||||
} /* if */
|
} /* if */
|
||||||
} /* if */
|
} /* if */
|
||||||
markusage(sym,uREAD | uWRITTEN);
|
p->value.ucell=(ucell)sym->addr;
|
||||||
*p=sym->addr;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
invalid_token:
|
invalid_token:
|
||||||
@ -6070,21 +6162,23 @@ static void SC_FASTCALL emit_param_data(ucell *p)
|
|||||||
} /* switch */
|
} /* switch */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SC_FASTCALL emit_param_local(ucell *p)
|
static void SC_FASTCALL emit_param_local(emit_outval *p)
|
||||||
{
|
{
|
||||||
cell val;
|
cell val;
|
||||||
char *str;
|
char *str;
|
||||||
symbol *sym;
|
symbol *sym;
|
||||||
int tok;
|
int tok;
|
||||||
|
|
||||||
|
p->type=eotNUMBER;
|
||||||
tok=lex(&val,&str);
|
tok=lex(&val,&str);
|
||||||
switch (tok) {
|
switch (tok) {
|
||||||
case tNUMBER:
|
case tNUMBER:
|
||||||
*p=val;
|
p->value.ucell=(ucell)val;
|
||||||
break;
|
break;
|
||||||
case tSYMBOL:
|
case tSYMBOL:
|
||||||
sym=findloc(str);
|
sym=findloc(str);
|
||||||
if (sym!=NULL) {
|
if (sym!=NULL) {
|
||||||
|
markusage(sym,uREAD | uWRITTEN);
|
||||||
if (sym->ident==iLABEL) {
|
if (sym->ident==iLABEL) {
|
||||||
tok=tLABEL;
|
tok=tLABEL;
|
||||||
goto invalid_token;
|
goto invalid_token;
|
||||||
@ -6095,13 +6189,16 @@ static void SC_FASTCALL emit_param_local(ucell *p)
|
|||||||
} /* if */
|
} /* if */
|
||||||
} else {
|
} else {
|
||||||
sym=findglb(str,sSTATEVAR);
|
sym=findglb(str,sSTATEVAR);
|
||||||
if (sym==NULL || sym->ident!=iCONSTEXPR) {
|
if (sym==NULL) {
|
||||||
|
undefined_sym:
|
||||||
error(17,str); /* undefined symbol */
|
error(17,str); /* undefined symbol */
|
||||||
break;
|
break;
|
||||||
} /* if */
|
} /* if */
|
||||||
} /* if */
|
|
||||||
markusage(sym,uREAD | uWRITTEN);
|
markusage(sym,uREAD | uWRITTEN);
|
||||||
*p=sym->addr;
|
if (sym->ident!=iCONSTEXPR)
|
||||||
|
goto undefined_sym;
|
||||||
|
} /* if */
|
||||||
|
p->value.ucell=(ucell)sym->addr;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
invalid_token:
|
invalid_token:
|
||||||
@ -6109,95 +6206,41 @@ static void SC_FASTCALL emit_param_local(ucell *p)
|
|||||||
} /* switch */
|
} /* switch */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SC_FASTCALL emit_param_index(ucell *p,const cell *valid_values,int numvalues)
|
static void SC_FASTCALL emit_param_label(emit_outval *p)
|
||||||
{
|
|
||||||
cell val;
|
|
||||||
char *str;
|
|
||||||
symbol *sym;
|
|
||||||
int tok,i,global;
|
|
||||||
int neg=FALSE;
|
|
||||||
|
|
||||||
assert(numvalues>0);
|
|
||||||
fetchtok:
|
|
||||||
tok=lex(&val,&str);
|
|
||||||
switch (tok) {
|
|
||||||
case tNUMBER:
|
|
||||||
if (neg!=FALSE)
|
|
||||||
val=-val;
|
|
||||||
break;
|
|
||||||
case tRATIONAL:
|
|
||||||
if (neg!=FALSE)
|
|
||||||
val=val|((cell)1 << (PAWN_CELL_SIZE-1));
|
|
||||||
break;
|
|
||||||
case tSYMBOL:
|
|
||||||
global=FALSE;
|
|
||||||
sym=findloc(str);
|
|
||||||
if (sym==NULL) {
|
|
||||||
global=TRUE;
|
|
||||||
sym=findglb(str,sSTATEVAR);
|
|
||||||
} /* if */
|
|
||||||
if (sym==NULL) {
|
|
||||||
error(17,str); /* undefined symbol */
|
|
||||||
return;
|
|
||||||
} /* if */
|
|
||||||
switch (sym->ident) {
|
|
||||||
case iCONSTEXPR:
|
|
||||||
break;
|
|
||||||
case iLABEL:
|
|
||||||
tok=tLABEL;
|
|
||||||
goto invalid_token;
|
|
||||||
case iFUNCTN:
|
|
||||||
case iREFFUNC:
|
|
||||||
tok=((sym->usage & uNATIVE)!=0) ? teNATIVE : teFUNCTN;
|
|
||||||
goto invalid_token;
|
|
||||||
default:
|
|
||||||
tok=(global==FALSE && sym->vclass!=sSTATIC) ? teLOCAL : teDATA;
|
|
||||||
goto invalid_token;
|
|
||||||
} /* switch */
|
|
||||||
markusage(sym,uREAD);
|
|
||||||
val=(neg!=FALSE) ? -sym->addr : sym->addr;
|
|
||||||
break;
|
|
||||||
case '-':
|
|
||||||
if (neg==FALSE) {
|
|
||||||
neg=TRUE;
|
|
||||||
goto fetchtok;
|
|
||||||
} /* if */
|
|
||||||
/* drop through */
|
|
||||||
default:
|
|
||||||
invalid_token:
|
|
||||||
emit_invalid_token(teNUMERIC,tok);
|
|
||||||
return;
|
|
||||||
} /* switch */
|
|
||||||
|
|
||||||
*p=val;
|
|
||||||
for (i=0; i<numvalues; i++)
|
|
||||||
if (val==valid_values[i])
|
|
||||||
return;
|
|
||||||
error(50); /* invalid range */
|
|
||||||
}
|
|
||||||
|
|
||||||
static void SC_FASTCALL emit_param_label(ucell *p)
|
|
||||||
{
|
{
|
||||||
cell val;
|
cell val;
|
||||||
char *str;
|
char *str;
|
||||||
symbol *sym;
|
symbol *sym;
|
||||||
int tok;
|
int tok;
|
||||||
|
|
||||||
|
p->type=eotNUMBER;
|
||||||
|
tok=lex(&val,&str);
|
||||||
|
switch (tok)
|
||||||
|
{
|
||||||
|
case ':':
|
||||||
tok=lex(&val,&str);
|
tok=lex(&val,&str);
|
||||||
if (tok!=tSYMBOL)
|
if (tok!=tSYMBOL)
|
||||||
emit_invalid_token(tSYMBOL,tok);
|
goto invalid_token;
|
||||||
|
/* fallthrough */
|
||||||
|
case tSYMBOL:
|
||||||
sym=fetchlab(str);
|
sym=fetchlab(str);
|
||||||
sym->usage|=uREAD;
|
sym->usage|=uREAD;
|
||||||
*p=*(ucell *)&sym->addr;
|
p->value.ucell=(ucell)sym->addr;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
invalid_token:
|
||||||
|
emit_invalid_token(tSYMBOL,tok);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SC_FASTCALL emit_param_function(ucell *p,int isnative)
|
static void SC_FASTCALL emit_param_function(emit_outval *p,int isnative)
|
||||||
{
|
{
|
||||||
cell val;
|
cell val;
|
||||||
char *str;
|
char *str;
|
||||||
symbol *sym;
|
symbol *sym;
|
||||||
int tok;
|
int tok;
|
||||||
|
|
||||||
|
p->type=eotNUMBER;
|
||||||
tok=lex(&val,&str);
|
tok=lex(&val,&str);
|
||||||
switch (tok)
|
switch (tok)
|
||||||
{
|
{
|
||||||
@ -6207,6 +6250,7 @@ static void SC_FASTCALL emit_param_function(ucell *p,int isnative)
|
|||||||
error(17,str); /* undefined symbol */
|
error(17,str); /* undefined symbol */
|
||||||
return;
|
return;
|
||||||
} /* if */
|
} /* if */
|
||||||
|
markusage(sym,uREAD);
|
||||||
if (sym->ident==iFUNCTN || sym->ident==iREFFUNC) {
|
if (sym->ident==iFUNCTN || sym->ident==iREFFUNC) {
|
||||||
if (!!(sym->usage & uNATIVE)==isnative)
|
if (!!(sym->usage & uNATIVE)==isnative)
|
||||||
break;
|
break;
|
||||||
@ -6214,7 +6258,7 @@ static void SC_FASTCALL emit_param_function(ucell *p,int isnative)
|
|||||||
} else {
|
} else {
|
||||||
tok=(sym->ident==iCONSTEXPR) ? teNUMERIC : teDATA;
|
tok=(sym->ident==iCONSTEXPR) ? teNUMERIC : teDATA;
|
||||||
} /* if */
|
} /* if */
|
||||||
/* drop through */
|
/* fallthrough */
|
||||||
default:
|
default:
|
||||||
emit_invalid_token((isnative!=FALSE) ? teNATIVE : teFUNCTN,tok);
|
emit_invalid_token((isnative!=FALSE) ? teNATIVE : teFUNCTN,tok);
|
||||||
return;
|
return;
|
||||||
@ -6223,11 +6267,11 @@ static void SC_FASTCALL emit_param_function(ucell *p,int isnative)
|
|||||||
if (isnative!=FALSE) {
|
if (isnative!=FALSE) {
|
||||||
if ((sym->usage & uREAD)==0 && sym->addr>=0)
|
if ((sym->usage & uREAD)==0 && sym->addr>=0)
|
||||||
sym->addr=ntv_funcid++;
|
sym->addr=ntv_funcid++;
|
||||||
*p=sym->addr;
|
p->value.ucell=(ucell)sym->addr;
|
||||||
} else {
|
} else {
|
||||||
*(char **)p=str;
|
p->type=eotFUNCTION;
|
||||||
|
p->value.string=str;
|
||||||
} /* if */
|
} /* if */
|
||||||
markusage(sym,uREAD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SC_FASTCALL emit_noop(char *name)
|
static void SC_FASTCALL emit_noop(char *name)
|
||||||
@ -6242,15 +6286,40 @@ static void SC_FASTCALL emit_parm0(char *name)
|
|||||||
|
|
||||||
static void SC_FASTCALL emit_parm1_any(char *name)
|
static void SC_FASTCALL emit_parm1_any(char *name)
|
||||||
{
|
{
|
||||||
ucell p[1];
|
emit_outval p[1];
|
||||||
|
|
||||||
emit_param_any(&p[0]);
|
emit_param_any(&p[0]);
|
||||||
outinstr(name,p,(sizeof p / sizeof p[0]));
|
outinstr(name,p,(sizeof p / sizeof p[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void SC_FASTCALL emit_parm1_integer(char *name)
|
||||||
|
{
|
||||||
|
emit_outval p[1];
|
||||||
|
|
||||||
|
emit_param_integer(&p[0]);
|
||||||
|
outinstr(name,p,(sizeof p / sizeof p[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SC_FASTCALL emit_parm1_nonneg(char *name)
|
||||||
|
{
|
||||||
|
emit_outval p[1];
|
||||||
|
|
||||||
|
emit_param_nonneg(&p[0]);
|
||||||
|
outinstr(name,p,(sizeof p / sizeof p[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SC_FASTCALL emit_parm1_shift(char *name)
|
||||||
|
{
|
||||||
|
static const cell valid_values[] = { 0,sizeof(cell)*8-1 };
|
||||||
|
emit_outval p[1];
|
||||||
|
|
||||||
|
emit_param_index(&p[0],TRUE,valid_values,(sizeof valid_values / sizeof valid_values[0]));
|
||||||
|
outinstr(name,p,(sizeof p / sizeof p[0]));
|
||||||
|
}
|
||||||
|
|
||||||
static void SC_FASTCALL emit_parm1_data(char *name)
|
static void SC_FASTCALL emit_parm1_data(char *name)
|
||||||
{
|
{
|
||||||
ucell p[1];
|
emit_outval p[1];
|
||||||
|
|
||||||
emit_param_data(&p[0]);
|
emit_param_data(&p[0]);
|
||||||
outinstr(name,p,(sizeof p / sizeof p[0]));
|
outinstr(name,p,(sizeof p / sizeof p[0]));
|
||||||
@ -6258,7 +6327,7 @@ static void SC_FASTCALL emit_parm1_data(char *name)
|
|||||||
|
|
||||||
static void SC_FASTCALL emit_parm1_local(char *name)
|
static void SC_FASTCALL emit_parm1_local(char *name)
|
||||||
{
|
{
|
||||||
ucell p[1];
|
emit_outval p[1];
|
||||||
|
|
||||||
emit_param_local(&p[0]);
|
emit_param_local(&p[0]);
|
||||||
outinstr(name,p,(sizeof p / sizeof p[0]));
|
outinstr(name,p,(sizeof p / sizeof p[0]));
|
||||||
@ -6266,7 +6335,7 @@ static void SC_FASTCALL emit_parm1_local(char *name)
|
|||||||
|
|
||||||
static void SC_FASTCALL emit_parm1_label(char *name)
|
static void SC_FASTCALL emit_parm1_label(char *name)
|
||||||
{
|
{
|
||||||
ucell p[1];
|
emit_outval p[1];
|
||||||
|
|
||||||
emit_param_label(&p[0]);
|
emit_param_label(&p[0]);
|
||||||
outinstr(name,p,(sizeof p / sizeof p[0]));
|
outinstr(name,p,(sizeof p / sizeof p[0]));
|
||||||
@ -6274,77 +6343,72 @@ static void SC_FASTCALL emit_parm1_label(char *name)
|
|||||||
|
|
||||||
static void SC_FASTCALL emit_do_casetbl(char *name)
|
static void SC_FASTCALL emit_do_casetbl(char *name)
|
||||||
{
|
{
|
||||||
ucell p[2];
|
emit_outval p[2];
|
||||||
|
|
||||||
(void)name;
|
(void)name;
|
||||||
emit_param_any(&p[0]);
|
emit_param_nonneg(&p[0]);
|
||||||
emit_param_label(&p[1]);
|
emit_param_label(&p[1]);
|
||||||
stgwrite("\tcasetbl\n");
|
stgwrite("\tcasetbl\n");
|
||||||
stgwrite("\tcase ");
|
outinstr("case",p,(sizeof p / sizeof p[0]));
|
||||||
outval(p[0],FALSE);
|
|
||||||
stgwrite(" ");
|
|
||||||
outval(p[1],TRUE);
|
|
||||||
code_idx+=opcodes(1)+opargs(2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SC_FASTCALL emit_do_case(char *name)
|
static void SC_FASTCALL emit_do_case(char *name)
|
||||||
{
|
{
|
||||||
ucell p[2];
|
emit_outval p[2];
|
||||||
|
|
||||||
emit_param_any(&p[0]);
|
emit_param_any(&p[0]);
|
||||||
emit_param_label(&p[1]);
|
emit_param_label(&p[1]);
|
||||||
stgwrite("\tcase ");
|
outinstr("case",p,(sizeof p / sizeof p[0]));
|
||||||
outval(p[0],FALSE);
|
code_idx-=opcodes(1);
|
||||||
stgwrite(" ");
|
|
||||||
outval(p[1],TRUE);
|
|
||||||
code_idx+=opargs(2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SC_FASTCALL emit_do_lodb_strb(char *name)
|
static void SC_FASTCALL emit_do_lodb_strb(char *name)
|
||||||
{
|
{
|
||||||
static const cell valid_values[] = { 1,2,4 };
|
static const cell valid_values[] = { 1,2,4 };
|
||||||
ucell p[1];
|
emit_outval p[1];
|
||||||
|
|
||||||
emit_param_index(&p[0],valid_values,(sizeof valid_values / sizeof valid_values[0]));
|
emit_param_index(&p[0],FALSE,valid_values,(sizeof valid_values / sizeof valid_values[0]));
|
||||||
|
outinstr(name,p,(sizeof p / sizeof p[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SC_FASTCALL emit_do_align(char *name)
|
||||||
|
{
|
||||||
|
static const cell valid_values[] = { 0,sizeof(cell)-1 };
|
||||||
|
emit_outval p[1];
|
||||||
|
|
||||||
|
emit_param_index(&p[0],TRUE,valid_values,(sizeof valid_values / sizeof valid_values[0]));
|
||||||
outinstr(name,p,(sizeof p / sizeof p[0]));
|
outinstr(name,p,(sizeof p / sizeof p[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SC_FASTCALL emit_do_lctrl(char *name)
|
static void SC_FASTCALL emit_do_lctrl(char *name)
|
||||||
{
|
{
|
||||||
static const cell valid_values[] = { 0,1,2,3,4,5,6,7,8,9 };
|
static const cell valid_values[] = { 0,9 };
|
||||||
ucell p[1];
|
emit_outval p[1];
|
||||||
|
|
||||||
emit_param_index(&p[0],valid_values,(sizeof valid_values / sizeof valid_values[0]));
|
emit_param_index(&p[0],TRUE,valid_values,(sizeof valid_values / sizeof valid_values[0]));
|
||||||
outinstr(name,p,(sizeof p / sizeof p[0]));
|
outinstr(name,p,(sizeof p / sizeof p[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SC_FASTCALL emit_do_sctrl(char *name)
|
static void SC_FASTCALL emit_do_sctrl(char *name)
|
||||||
{
|
{
|
||||||
static const cell valid_values[] = { 2,4,5,6,8,9 };
|
static const cell valid_values[] = { 2,4,5,6,8,9 };
|
||||||
ucell p[1];
|
emit_outval p[1];
|
||||||
|
|
||||||
emit_param_index(&p[0],valid_values,(sizeof valid_values / sizeof valid_values[0]));
|
emit_param_index(&p[0],FALSE,valid_values,(sizeof valid_values / sizeof valid_values[0]));
|
||||||
outinstr(name,p,(sizeof p / sizeof p[0]));
|
outinstr(name,p,(sizeof p / sizeof p[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SC_FASTCALL emit_do_call(char *name)
|
static void SC_FASTCALL emit_do_call(char *name)
|
||||||
{
|
{
|
||||||
char *funcname=NULL;
|
emit_outval p[1];
|
||||||
|
|
||||||
emit_param_function((ucell *)&funcname,FALSE);
|
emit_param_function(&p[0],FALSE);
|
||||||
stgwrite("\t");
|
outinstr(name,p,(sizeof p / sizeof p[0]));
|
||||||
stgwrite(name);
|
|
||||||
if (funcname!=NULL) {
|
|
||||||
stgwrite(" .");
|
|
||||||
stgwrite(funcname);
|
|
||||||
} /* if */
|
|
||||||
stgwrite("\n");
|
|
||||||
code_idx+=opcodes(1)+opargs(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SC_FASTCALL emit_do_sysreq_c(char *name)
|
static void SC_FASTCALL emit_do_sysreq_c(char *name)
|
||||||
{
|
{
|
||||||
ucell p[1];
|
emit_outval p[1];
|
||||||
|
|
||||||
emit_param_function(&p[0],TRUE);
|
emit_param_function(&p[0],TRUE);
|
||||||
|
|
||||||
@ -6363,7 +6427,7 @@ static void SC_FASTCALL emit_do_sysreq_c(char *name)
|
|||||||
|
|
||||||
static void SC_FASTCALL emit_do_sysreq_n(char *name)
|
static void SC_FASTCALL emit_do_sysreq_n(char *name)
|
||||||
{
|
{
|
||||||
ucell p[2];
|
emit_outval p[2];
|
||||||
|
|
||||||
emit_param_function(&p[0],TRUE);
|
emit_param_function(&p[0],TRUE);
|
||||||
emit_param_any(&p[1]);
|
emit_param_any(&p[1]);
|
||||||
@ -6379,14 +6443,14 @@ static void SC_FASTCALL emit_do_sysreq_n(char *name)
|
|||||||
} else {
|
} else {
|
||||||
outinstr("push.c",&p[1],1);
|
outinstr("push.c",&p[1],1);
|
||||||
outinstr("sysreq.c",&p[0],1);
|
outinstr("sysreq.c",&p[0],1);
|
||||||
p[1]+=sizeof(cell);
|
p[1].value.ucell+=sizeof(cell);
|
||||||
outinstr("stack",&p[1],1);
|
outinstr("stack",&p[1],1);
|
||||||
} /* if */
|
} /* if */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SC_FASTCALL emit_do_const(char *name)
|
static void SC_FASTCALL emit_do_const(char *name)
|
||||||
{
|
{
|
||||||
ucell p[2];
|
emit_outval p[2];
|
||||||
|
|
||||||
emit_param_data(&p[0]);
|
emit_param_data(&p[0]);
|
||||||
emit_param_any(&p[1]);
|
emit_param_any(&p[1]);
|
||||||
@ -6410,7 +6474,7 @@ static void SC_FASTCALL emit_do_const(char *name)
|
|||||||
|
|
||||||
static void SC_FASTCALL emit_do_const_s(char *name)
|
static void SC_FASTCALL emit_do_const_s(char *name)
|
||||||
{
|
{
|
||||||
ucell p[2];
|
emit_outval p[2];
|
||||||
|
|
||||||
emit_param_local(&p[0]);
|
emit_param_local(&p[0]);
|
||||||
emit_param_any(&p[1]);
|
emit_param_any(&p[1]);
|
||||||
@ -6434,7 +6498,7 @@ static void SC_FASTCALL emit_do_const_s(char *name)
|
|||||||
|
|
||||||
static void SC_FASTCALL emit_do_load_both(char *name)
|
static void SC_FASTCALL emit_do_load_both(char *name)
|
||||||
{
|
{
|
||||||
ucell p[2];
|
emit_outval p[2];
|
||||||
|
|
||||||
emit_param_data(&p[0]);
|
emit_param_data(&p[0]);
|
||||||
emit_param_data(&p[1]);
|
emit_param_data(&p[1]);
|
||||||
@ -6454,7 +6518,7 @@ static void SC_FASTCALL emit_do_load_both(char *name)
|
|||||||
|
|
||||||
static void SC_FASTCALL emit_do_load_s_both(char *name)
|
static void SC_FASTCALL emit_do_load_s_both(char *name)
|
||||||
{
|
{
|
||||||
ucell p[2];
|
emit_outval p[2];
|
||||||
|
|
||||||
emit_param_local(&p[0]);
|
emit_param_local(&p[0]);
|
||||||
emit_param_local(&p[1]);
|
emit_param_local(&p[1]);
|
||||||
@ -6474,7 +6538,7 @@ static void SC_FASTCALL emit_do_load_s_both(char *name)
|
|||||||
|
|
||||||
static void SC_FASTCALL emit_do_pushn_c(char *name)
|
static void SC_FASTCALL emit_do_pushn_c(char *name)
|
||||||
{
|
{
|
||||||
ucell p[5];
|
emit_outval p[5];
|
||||||
int i,numargs;
|
int i,numargs;
|
||||||
|
|
||||||
assert(name[0]=='p' && name[1]=='u' && name[2]=='s'
|
assert(name[0]=='p' && name[1]=='u' && name[2]=='s'
|
||||||
@ -6496,7 +6560,7 @@ static void SC_FASTCALL emit_do_pushn_c(char *name)
|
|||||||
|
|
||||||
static void SC_FASTCALL emit_do_pushn(char *name)
|
static void SC_FASTCALL emit_do_pushn(char *name)
|
||||||
{
|
{
|
||||||
ucell p[5];
|
emit_outval p[5];
|
||||||
int i,numargs;
|
int i,numargs;
|
||||||
|
|
||||||
assert(name[0]=='p' && name[1]=='u' && name[2]=='s'
|
assert(name[0]=='p' && name[1]=='u' && name[2]=='s'
|
||||||
@ -6518,7 +6582,7 @@ static void SC_FASTCALL emit_do_pushn(char *name)
|
|||||||
|
|
||||||
static void SC_FASTCALL emit_do_pushn_s_adr(char *name)
|
static void SC_FASTCALL emit_do_pushn_s_adr(char *name)
|
||||||
{
|
{
|
||||||
ucell p[5];
|
emit_outval p[5];
|
||||||
int i,numargs;
|
int i,numargs;
|
||||||
|
|
||||||
assert(name[0]=='p' && name[1]=='u' && name[2]=='s'
|
assert(name[0]=='p' && name[1]=='u' && name[2]=='s'
|
||||||
@ -6545,16 +6609,16 @@ static EMIT_OPCODE emit_opcodelist[] = {
|
|||||||
{ 87, "add.c", emit_parm1_any },
|
{ 87, "add.c", emit_parm1_any },
|
||||||
{ 14, "addr.alt", emit_parm1_local },
|
{ 14, "addr.alt", emit_parm1_local },
|
||||||
{ 13, "addr.pri", emit_parm1_local },
|
{ 13, "addr.pri", emit_parm1_local },
|
||||||
{ 30, "align.alt", emit_parm1_any },
|
{ 30, "align.alt", emit_do_align },
|
||||||
{ 29, "align.pri", emit_parm1_any },
|
{ 29, "align.pri", emit_do_align },
|
||||||
{ 81, "and", emit_parm0 },
|
{ 81, "and", emit_parm0 },
|
||||||
{121, "bounds", emit_parm1_any },
|
{121, "bounds", emit_parm1_integer },
|
||||||
{137, "break", emit_parm0 },
|
{137, "break", emit_parm0 },
|
||||||
{ 49, "call", emit_do_call },
|
{ 49, "call", emit_do_call },
|
||||||
{ 50, "call.pri", emit_parm0 },
|
{ 50, "call.pri", emit_parm0 },
|
||||||
{ 0, "case", emit_do_case },
|
{ 0, "case", emit_do_case },
|
||||||
{130, "casetbl", emit_do_casetbl },
|
{130, "casetbl", emit_do_casetbl },
|
||||||
{118, "cmps", emit_parm1_any },
|
{118, "cmps", emit_parm1_nonneg },
|
||||||
{156, "const", emit_do_const },
|
{156, "const", emit_do_const },
|
||||||
{ 12, "const.alt", emit_parm1_any },
|
{ 12, "const.alt", emit_parm1_any },
|
||||||
{ 11, "const.pri", emit_parm1_any },
|
{ 11, "const.pri", emit_parm1_any },
|
||||||
@ -6567,13 +6631,13 @@ static EMIT_OPCODE emit_opcodelist[] = {
|
|||||||
{ 95, "eq", emit_parm0 },
|
{ 95, "eq", emit_parm0 },
|
||||||
{106, "eq.c.alt", emit_parm1_any },
|
{106, "eq.c.alt", emit_parm1_any },
|
||||||
{105, "eq.c.pri", emit_parm1_any },
|
{105, "eq.c.pri", emit_parm1_any },
|
||||||
{119, "fill", emit_parm1_any },
|
{119, "fill", emit_parm1_nonneg },
|
||||||
{100, "geq", emit_parm0 },
|
{100, "geq", emit_parm0 },
|
||||||
{ 99, "grtr", emit_parm0 },
|
{ 99, "grtr", emit_parm0 },
|
||||||
{120, "halt", emit_parm1_any },
|
{120, "halt", emit_parm1_nonneg },
|
||||||
{ 45, "heap", emit_parm1_any },
|
{ 45, "heap", emit_parm1_integer },
|
||||||
{ 27, "idxaddr", emit_parm0 },
|
{ 27, "idxaddr", emit_parm0 },
|
||||||
{ 28, "idxaddr.b", emit_parm1_any },
|
{ 28, "idxaddr.b", emit_parm1_shift },
|
||||||
{109, "inc", emit_parm1_data },
|
{109, "inc", emit_parm1_data },
|
||||||
{108, "inc.alt", emit_parm0 },
|
{108, "inc.alt", emit_parm0 },
|
||||||
{111, "inc.i", emit_parm0 },
|
{111, "inc.i", emit_parm0 },
|
||||||
@ -6587,7 +6651,7 @@ static EMIT_OPCODE emit_opcodelist[] = {
|
|||||||
{ 57, "jless", emit_parm1_label },
|
{ 57, "jless", emit_parm1_label },
|
||||||
{ 56, "jneq", emit_parm1_label },
|
{ 56, "jneq", emit_parm1_label },
|
||||||
{ 54, "jnz", emit_parm1_label },
|
{ 54, "jnz", emit_parm1_label },
|
||||||
{ 52, "jrel", emit_parm1_any },
|
{ 52, "jrel", emit_parm1_integer },
|
||||||
{ 64, "jsgeq", emit_parm1_label },
|
{ 64, "jsgeq", emit_parm1_label },
|
||||||
{ 63, "jsgrtr", emit_parm1_label },
|
{ 63, "jsgrtr", emit_parm1_label },
|
||||||
{ 62, "jsleq", emit_parm1_label },
|
{ 62, "jsleq", emit_parm1_label },
|
||||||
@ -6599,7 +6663,7 @@ static EMIT_OPCODE emit_opcodelist[] = {
|
|||||||
{ 98, "leq", emit_parm0 },
|
{ 98, "leq", emit_parm0 },
|
||||||
{ 97, "less", emit_parm0 },
|
{ 97, "less", emit_parm0 },
|
||||||
{ 25, "lidx", emit_parm0 },
|
{ 25, "lidx", emit_parm0 },
|
||||||
{ 26, "lidx.b", emit_parm1_any },
|
{ 26, "lidx.b", emit_parm1_shift },
|
||||||
{ 2, "load.alt", emit_parm1_data },
|
{ 2, "load.alt", emit_parm1_data },
|
||||||
{154, "load.both", emit_do_load_both },
|
{154, "load.both", emit_do_load_both },
|
||||||
{ 9, "load.i", emit_parm0 },
|
{ 9, "load.i", emit_parm0 },
|
||||||
@ -6614,7 +6678,7 @@ static EMIT_OPCODE emit_opcodelist[] = {
|
|||||||
{ 7, "lref.s.pri", emit_parm1_local },
|
{ 7, "lref.s.pri", emit_parm1_local },
|
||||||
{ 34, "move.alt", emit_parm0 },
|
{ 34, "move.alt", emit_parm0 },
|
||||||
{ 33, "move.pri", emit_parm0 },
|
{ 33, "move.pri", emit_parm0 },
|
||||||
{117, "movs", emit_parm1_any },
|
{117, "movs", emit_parm1_nonneg },
|
||||||
{ 85, "neg", emit_parm0 },
|
{ 85, "neg", emit_parm0 },
|
||||||
{ 96, "neq", emit_parm0 },
|
{ 96, "neq", emit_parm0 },
|
||||||
{134, "nop", emit_parm0 },
|
{134, "nop", emit_parm0 },
|
||||||
@ -6628,7 +6692,7 @@ static EMIT_OPCODE emit_opcodelist[] = {
|
|||||||
{ 37, "push.alt", emit_parm0 },
|
{ 37, "push.alt", emit_parm0 },
|
||||||
{ 39, "push.c", emit_parm1_any },
|
{ 39, "push.c", emit_parm1_any },
|
||||||
{ 36, "push.pri", emit_parm0 },
|
{ 36, "push.pri", emit_parm0 },
|
||||||
{ 38, "push.r", emit_parm1_any },
|
{ 38, "push.r", emit_parm1_integer },
|
||||||
{ 41, "push.s", emit_parm1_local },
|
{ 41, "push.s", emit_parm1_local },
|
||||||
{139, "push2", emit_do_pushn },
|
{139, "push2", emit_do_pushn },
|
||||||
{141, "push2.adr", emit_do_pushn_s_adr },
|
{141, "push2.adr", emit_do_pushn_s_adr },
|
||||||
@ -6654,23 +6718,23 @@ static EMIT_OPCODE emit_opcodelist[] = {
|
|||||||
{104, "sgeq", emit_parm0 },
|
{104, "sgeq", emit_parm0 },
|
||||||
{103, "sgrtr", emit_parm0 },
|
{103, "sgrtr", emit_parm0 },
|
||||||
{ 65, "shl", emit_parm0 },
|
{ 65, "shl", emit_parm0 },
|
||||||
{ 69, "shl.c.alt", emit_parm1_any },
|
{ 69, "shl.c.alt", emit_parm1_shift },
|
||||||
{ 68, "shl.c.pri", emit_parm1_any },
|
{ 68, "shl.c.pri", emit_parm1_shift },
|
||||||
{ 66, "shr", emit_parm0 },
|
{ 66, "shr", emit_parm0 },
|
||||||
{ 71, "shr.c.alt", emit_parm1_any },
|
{ 71, "shr.c.alt", emit_parm1_shift },
|
||||||
{ 70, "shr.c.pri", emit_parm1_any },
|
{ 70, "shr.c.pri", emit_parm1_shift },
|
||||||
{ 94, "sign.alt", emit_parm0 },
|
{ 94, "sign.alt", emit_parm0 },
|
||||||
{ 93, "sign.pri", emit_parm0 },
|
{ 93, "sign.pri", emit_parm0 },
|
||||||
{102, "sleq", emit_parm0 },
|
{102, "sleq", emit_parm0 },
|
||||||
{101, "sless", emit_parm0 },
|
{101, "sless", emit_parm0 },
|
||||||
{ 72, "smul", emit_parm0 },
|
{ 72, "smul", emit_parm0 },
|
||||||
{ 88, "smul.c", emit_parm1_any },
|
{ 88, "smul.c", emit_parm1_integer },
|
||||||
{ 20, "sref.alt", emit_parm1_data },
|
{ 20, "sref.alt", emit_parm1_data },
|
||||||
{ 19, "sref.pri", emit_parm1_data },
|
{ 19, "sref.pri", emit_parm1_data },
|
||||||
{ 22, "sref.s.alt", emit_parm1_local },
|
{ 22, "sref.s.alt", emit_parm1_local },
|
||||||
{ 21, "sref.s.pri", emit_parm1_local },
|
{ 21, "sref.s.pri", emit_parm1_local },
|
||||||
{ 67, "sshr", emit_parm0 },
|
{ 67, "sshr", emit_parm0 },
|
||||||
{ 44, "stack", emit_parm1_any },
|
{ 44, "stack", emit_parm1_integer },
|
||||||
{ 16, "stor.alt", emit_parm1_data },
|
{ 16, "stor.alt", emit_parm1_data },
|
||||||
{ 23, "stor.i", emit_parm0 },
|
{ 23, "stor.i", emit_parm0 },
|
||||||
{ 15, "stor.pri", emit_parm1_data },
|
{ 15, "stor.pri", emit_parm1_data },
|
||||||
@ -6700,10 +6764,7 @@ static int emit_findopcode(const char *instr,int maxlen)
|
|||||||
{
|
{
|
||||||
int low,high,mid,cmp;
|
int low,high,mid,cmp;
|
||||||
|
|
||||||
/* look up the instruction with a binary search
|
/* look up the instruction with a binary search */
|
||||||
* the assembler is case insensitive to instructions (but case sensitive
|
|
||||||
* to symbols)
|
|
||||||
*/
|
|
||||||
low=1; /* entry 0 is reserved (for "not found") */
|
low=1; /* entry 0 is reserved (for "not found") */
|
||||||
high=(sizeof emit_opcodelist / sizeof emit_opcodelist[0])-1;
|
high=(sizeof emit_opcodelist / sizeof emit_opcodelist[0])-1;
|
||||||
while (low<high) {
|
while (low<high) {
|
||||||
@ -6724,12 +6785,12 @@ static int emit_findopcode(const char *instr,int maxlen)
|
|||||||
|
|
||||||
SC_FUNC void emit_parse_line(void)
|
SC_FUNC void emit_parse_line(void)
|
||||||
{
|
{
|
||||||
|
extern char *sc_tokens[];
|
||||||
cell val;
|
cell val;
|
||||||
char* st;
|
char* st;
|
||||||
int tok,len,i;
|
int tok,len,i;
|
||||||
symbol *sym;
|
symbol *sym;
|
||||||
char name[MAX_INSTR_LEN];
|
char name[MAX_INSTR_LEN];
|
||||||
extern char *sc_tokens[];
|
|
||||||
|
|
||||||
tok=tokeninfo(&val,&st);
|
tok=tokeninfo(&val,&st);
|
||||||
if (tok==tSYMBOL || (tok>tMIDDLE && tok<=tLAST)) {
|
if (tok==tSYMBOL || (tok>tMIDDLE && tok<=tLAST)) {
|
||||||
|
@ -2097,8 +2097,8 @@ char *sc_tokens[] = {
|
|||||||
"#tryinclude", "#undef", "#warning",
|
"#tryinclude", "#undef", "#warning",
|
||||||
";", ";", "-integer value-", "-rational value-", "-identifier-",
|
";", ";", "-integer value-", "-rational value-", "-identifier-",
|
||||||
"-label-", "-string-",
|
"-label-", "-string-",
|
||||||
"-numeric value-", "-data offset-", "-local variable-", "-function-",
|
"-any value-", "-numeric value-", "-data offset-", "-local variable-",
|
||||||
"-native function-"
|
"-function-", "-native function-", "-nonnegative integer-"
|
||||||
};
|
};
|
||||||
|
|
||||||
SC_FUNC int lex(cell *lexvalue,char **lexsym)
|
SC_FUNC int lex(cell *lexvalue,char **lexsym)
|
||||||
|
@ -1379,19 +1379,31 @@ SC_FUNC void outval(cell val,int newline)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* write an instruction with arguments */
|
/* write an instruction with arguments */
|
||||||
SC_FUNC void outinstr(const char *name,ucell args[],int numargs)
|
SC_FUNC void outinstr(const char *name,emit_outval params[],int numparams)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
stgwrite("\t");
|
stgwrite("\t");
|
||||||
stgwrite(name);
|
stgwrite(name);
|
||||||
|
|
||||||
for (i=0; i<numargs; i++) {
|
for (i=0; i<numparams; i++) {
|
||||||
stgwrite(" ");
|
stgwrite(" ");
|
||||||
stgwrite(itoh(args[i]));
|
switch (params[i].type)
|
||||||
|
{
|
||||||
|
case eotLABEL:
|
||||||
|
stgwrite("l.");
|
||||||
|
/* fallthrough */
|
||||||
|
case eotNUMBER:
|
||||||
|
stgwrite(itoh(params[i].value.ucell));
|
||||||
|
break;
|
||||||
|
case eotFUNCTION:
|
||||||
|
stgwrite(".");
|
||||||
|
stgwrite(params[i].value.string);
|
||||||
|
break;
|
||||||
|
}
|
||||||
} /* for */
|
} /* for */
|
||||||
|
|
||||||
stgwrite("\n");
|
stgwrite("\n");
|
||||||
|
|
||||||
code_idx+=opargs(numargs)+opcodes(1);
|
code_idx+=opcodes(1)+opargs(numparams);
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,7 @@ static ucell getparam(const char *s,char **n)
|
|||||||
char name[sNAMEMAX+1];
|
char name[sNAMEMAX+1];
|
||||||
symbol *sym;
|
symbol *sym;
|
||||||
|
|
||||||
if (*s=='.') {
|
if (s[0]=='.') {
|
||||||
/* this is a function, find it in the global symbol table */
|
/* this is a function, find it in the global symbol table */
|
||||||
for (i=0; !isspace(*(++s)); i++) {
|
for (i=0; !isspace(*(++s)); i++) {
|
||||||
assert(*s!='\0');
|
assert(*s!='\0');
|
||||||
@ -115,6 +115,12 @@ static ucell getparam(const char *s,char **n)
|
|||||||
assert(sym->ident==iFUNCTN || sym->ident==iREFFUNC);
|
assert(sym->ident==iFUNCTN || sym->ident==iREFFUNC);
|
||||||
assert(sym->vclass==sGLOBAL);
|
assert(sym->vclass==sGLOBAL);
|
||||||
result=sym->addr;
|
result=sym->addr;
|
||||||
|
} else if (s[0]=='l' && s[1]=='.') {
|
||||||
|
/* this is a label */
|
||||||
|
i=(int)hex2long(s+2,NULL);
|
||||||
|
assert(i>=0 && i<sc_labnum);
|
||||||
|
assert(lbltab!=NULL);
|
||||||
|
result=lbltab[i];
|
||||||
} else {
|
} else {
|
||||||
for ( ;; ) {
|
for ( ;; ) {
|
||||||
result+=hex2long(s,(char**)&s);
|
result+=hex2long(s,(char**)&s);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user