diff --git a/extree.c b/extree.c index d11c84e..3663667 100644 --- a/extree.c +++ b/extree.c @@ -7,6 +7,8 @@ #include "util.h" #include "assemble_globals.h" +#include "assemble_aux.h" +#include "listing.h" #include "object.h" @@ -24,6 +26,10 @@ void print_tree( { SYMBOL *sym; + if (printfile == NULL) { + return; + } + if (tp == NULL) { fprintf(printfile, "(null)"); return; @@ -57,6 +63,12 @@ void print_tree( fputc('>', printfile); break; + case EX_REG: + fprintf(printfile, "%%<"); + print_tree(printfile, tp->data.child.left, depth + 4); + fputc('>', printfile); + break; + case EX_ERR: fprintf(printfile, "{expression error}"); if (tp->data.child.left) { @@ -146,6 +158,7 @@ int num_subtrees( case EX_COM: case EX_NEG: + case EX_REG: case EX_ERR: return 1; @@ -403,6 +416,25 @@ EX_TREE *evaluate( } break; + case EX_REG: + /* Evaluate as a literal, and create a register label */ + { + res = evaluate(tp->data.child.left, flags); + int regno = get_register(res); + + if (regno == NO_REG) { + report(NULL, "Register expression out of range.\n"); + res = ex_err(res, res->cp); + } else { + EX_TREE *newresult = new_ex_tree(EX_SYM); + + newresult->cp = res->cp; + newresult->data.symbol = reg_sym[regno]; + res = newresult; + } + } + break; + case EX_ERR: /* Copy */ res = dup_tree(tp); diff --git a/extree.h b/extree.h index 4d73a4c..69dc509 100644 --- a/extree.h +++ b/extree.h @@ -5,7 +5,8 @@ #include "symbols.h" typedef struct ex_tree { - enum ex_type { EX_LIT = 1, + enum ex_type { + EX_LIT = 1, /* Expression is a literal value */ EX_SYM = 2, /* Expression has a symbol reference @@ -19,6 +20,8 @@ typedef struct ex_tree { /* One's complement */ EX_NEG = 6, /* Negate */ + EX_REG = 7, + /* register value (%) */ EX_ERR = 8, /* Expression with an error */ diff --git a/parse.c b/parse.c index beaeb3a..859979f 100644 --- a/parse.c +++ b/parse.c @@ -892,17 +892,7 @@ EX_TREE *parse_unary( cp = skipwhite(cp); if (*cp == '%') { /* Register notation */ - unsigned reg; - - cp++; - reg = strtoul(cp, &cp, 8); - if (reg > 7) - return ex_err(NULL, cp); - - /* This returns references to the built-in register symbols */ - tp = new_ex_tree(EX_SYM); - tp->data.symbol = reg_sym[reg]; - tp->cp = cp; + tp = new_ex_una(EX_REG, parse_unary(cp + 1)); return tp; } diff --git a/tests/test-operands.lst.ok b/tests/test-operands.lst.ok index b04e8b2..f3696d3 100644 --- a/tests/test-operands.lst.ok +++ b/tests/test-operands.lst.ok @@ -41,6 +41,7 @@ test-operands.mac:32: ***ERROR Junk at end of line (',(r0) ; bad 32 000042 005700 tst r0,(r0) ; bad test-operands.mac:33: ***ERROR Invalid addressing mode (Invalid expression) 33 tst @ ; bad +**:0: ***ERROR Register expression out of range. test-operands.mac:34: ***ERROR Invalid addressing mode (Invalid expression) 34 tst %77 ; bad test-operands.mac:35: ***ERROR Invalid addressing mode (Invalid expression) diff --git a/tests/test-reg.mac b/tests/test-reg.mac index e708f3b..bc4b402 100644 --- a/tests/test-reg.mac +++ b/tests/test-reg.mac @@ -13,6 +13,8 @@ ; It specifically mentions %3+1 to be the same as %4. ; For the rest there is no indication where exactly register labels can be used. + .psect abs,abs + A = 1 l1 = %1 @@ -34,24 +36,58 @@ B = rti ; 2 l10 = %B - l11 = %wait ; 1 + l11 = %wait ; 1 l12 = %1. l13 = %7. - l14 = %10 ; error: too large - l15 = %8. ; error: too large + l14 = %10 ; error: too large (error R), but symbol is still def'd + l15 = %8. ; error: too large (error R), but symbol is still def'd - mov #%2,%2 ; must not be a relocatable expression! - mov #l1,%2 ; must not be a relocatable expression! - mov #<%1+%2>,%3 ; must not be a relocatable expression! - mov #,%3 ; must not be a relocatable expression! - mov #<%l1+1>,%3 ; must not be a relocatable expression! + mov #%2,%2 ; 012702 000002 must be absolute, not reloc! + mov #l1,%2 ; 012702 000001 (idem) + mov #<%1+%2>,%3 ; 012703 000003 (idem) + mov #,%3 ; 012703 000002 (idem) + mov #<%l1+1>,%3 ; 012703 000002 (idem) + mov #r0,%2 ; 012702 000000 (idem) +here: mov #here,%2 + mov #rti,%2 - l20 = %l1 - l21 = %l20 + mov %2,%2 ; 010202 + mov l1,%2 ; 010102 + mov <%1+%2>,%3 ; 010303 + mov ,%3 ; 010203 + mov R1+1,%3 ; 010203 + mov <%l1+1>,%3 ; 010203 - l22 = l1 ; still a register - l23 = l22 ; still a register + mov %1,r2 ; mov r1,r2 + mov %0+1,r2 ; mov r1,r2 + mov %<0+1>,r2 ; mov r1,r2 + + mov r0,r2 ; mov r0,r2 + mov r0+1,r2 ; mov r1,r2 + mov r1+7,r2 ; error: too large +; R 58 000066 016702 000010' mov r1+7,r2 ; too large + + ; this shows that after a % comes a unary expr, + ; not an arbitrary binary expr: + l30 = 1+%2*2 ; %6. + l31 = <1+%2>*3 ; %9. error: too large, but symbol is still defined (R error) + mov l31,r0 ; error: bad register; code 011100 (R error) + l32 = 1+%<2*2> ; %5 + l33 = 1+<%2*2> ; %5 + + + l20 = %l1 + l21 = %l20 + + l22 = l1 ; still a register + l23 = l22 ; still a register + + .globl extrn + l40 = %extrn ; A error; L40 =%****** + mov l40,r0 ; U error; code 010000 + + word r0,wait,%2 ; 0, 1, 2 .end