diff --git a/assemble.c b/assemble.c index 6257542..1d51214 100644 --- a/assemble.c +++ b/assemble.c @@ -30,6 +30,8 @@ /* This function is way way too large, because I just coded most of the operation code and pseudo-op handling right in line. */ +/* FIXME: nobody checks for extra junk after a valid statement */ + static int assemble( STACK *stack, TEXT_RLD *tr) @@ -1605,6 +1607,31 @@ static int assemble( } return 1; +#if 0 +/* + * Although it is arguable that the FPP TSTF/TSTD instruction has 1 + * operand which is a floating point source, the PDP11 Architecture + * Handbook describes it as a destination, and MACRO11 V05.05 doesn't + * allow a FP literal argument. + */ + case OC_FPPSRC: + /* One fp immediate or a general addressing mode */ { + ADDR_MODE mode; + unsigned word; + + if (!get_fp_src_mode(cp, &cp, &mode)) { + report(stack->top, "Illegal addressing mode\n"); + return 0; + } + + /* Build instruction word */ + word = op->value | mode.type; + store_word(stack->top, tr, 2, word); + mode_extension(tr, &mode, stack->top); + } + return 1; +#endif + case OC_FPPGENAC: /* One one gen and one reg 0-3 */ { ADDR_MODE mode; @@ -1612,7 +1639,7 @@ static int assemble( unsigned reg; unsigned word; - if (!get_mode(cp, &cp, &mode)) { + if (!get_fp_src_mode(cp, &cp, &mode)) { report(stack->top, "Illegal addressing mode\n"); return 0; } @@ -1635,7 +1662,7 @@ static int assemble( /* * We could check here that the general mode - * is not R6 or R7, but the original Macro11 + * is not AC6 or AC7, but the original Macro11 * doesn't do that either. */ word = op->value | mode.type | (reg << 6); @@ -1676,8 +1703,11 @@ static int assemble( /* * We could check here that the general mode - * is not R6 or R7, but the original Macro11 + * is not AC6 or AC7, but the original Macro11 * doesn't do that either. + * + * For some (mostly STore instructions) the + * destination isn't a FDST but a plain DST. */ word = op->value | mode.type | (reg << 6); store_word(stack->top, tr, 2, word); diff --git a/parse.c b/parse.c index 44c7794..400c138 100644 --- a/parse.c +++ b/parse.c @@ -318,6 +318,45 @@ int get_mode( return TRUE; } +/* get_fp_src_mode - parse an immediate fp literal or a general mode */ + +int get_fp_src_mode( + char *cp, + char **endp, + ADDR_MODE *mode) +{ + cp = skipwhite(cp); + + char *savecp = cp; + + if (cp[0] == '#') { + unsigned flt[1]; + char *fltendp = NULL; + + cp = skipwhite(cp + 1); + + int ret = parse_float(cp, &fltendp, 1, flt); + + if (ret) { + mode->type = 027; + mode->rel = 0; + mode->offset = new_ex_lit(flt[0]); + mode->offset->cp = fltendp; + + if (endp) + *endp = mode->offset->cp; + + return TRUE; + } else if (fltendp) { + /* it looked like a fp number but something was wrong with it */ + } + } + + int ret = get_mode(savecp, endp, mode); + + return ret; +} + #define DEBUG_FLOAT 0 #if DEBUG_FLOAT diff --git a/parse.h b/parse.h index 84f50d9..a2b71ec 100644 --- a/parse.h +++ b/parse.h @@ -37,6 +37,10 @@ int get_mode( char *cp, char **endp, ADDR_MODE *mode); +int get_fp_src_mode( + char *cp, + char **endp, + ADDR_MODE *mode); EX_TREE *parse_expr( char *cp, diff --git a/symbols.c b/symbols.c index 3a344eb..2615d97 100644 --- a/symbols.c +++ b/symbols.c @@ -414,13 +414,14 @@ void add_symbols( add_sym("XOR", I_XOR, OC_JSR, &instruction_section, &system_st); add_sym("MFPT", I_MFPT, OC_NONE, &instruction_section, &system_st); - add_sym("ABSD", I_ABSD, OC_1GEN, &instruction_section, &system_st); - add_sym("ABSF", I_ABSF, OC_1GEN, &instruction_section, &system_st); + /* FPP instructions */ + add_sym("ABSD", I_ABSD, OC_FPPDST, &instruction_section, &system_st); + add_sym("ABSF", I_ABSF, OC_FPPDST, &instruction_section, &system_st); add_sym("ADDD", I_ADDD, OC_FPPGENAC, &instruction_section, &system_st); add_sym("ADDF", I_ADDF, OC_FPPGENAC, &instruction_section, &system_st); add_sym("CFCC", I_CFCC, OC_NONE, &instruction_section, &system_st); - add_sym("CLRD", I_CLRD, OC_1GEN, &instruction_section, &system_st); - add_sym("CLRF", I_CLRF, OC_1GEN, &instruction_section, &system_st); + add_sym("CLRD", I_CLRD, OC_FPPDST, &instruction_section, &system_st); + add_sym("CLRF", I_CLRF, OC_FPPDST, &instruction_section, &system_st); add_sym("CMPD", I_CMPD, OC_FPPGENAC, &instruction_section, &system_st); add_sym("CMPF", I_CMPF, OC_FPPGENAC, &instruction_section, &system_st); add_sym("DIVD", I_DIVD, OC_FPPGENAC, &instruction_section, &system_st); @@ -438,8 +439,8 @@ void add_symbols( add_sym("MODF", I_MODF, OC_FPPGENAC, &instruction_section, &system_st); add_sym("MULD", I_MULD, OC_FPPGENAC, &instruction_section, &system_st); add_sym("MULF", I_MULF, OC_FPPGENAC, &instruction_section, &system_st); - add_sym("NEGD", I_NEGD, OC_1GEN, &instruction_section, &system_st); - add_sym("NEGF", I_NEGF, OC_1GEN, &instruction_section, &system_st); + add_sym("NEGD", I_NEGD, OC_FPPDST, &instruction_section, &system_st); + add_sym("NEGF", I_NEGF, OC_FPPDST, &instruction_section, &system_st); add_sym("SETD", I_SETD, OC_NONE, &instruction_section, &system_st); add_sym("SETF", I_SETF, OC_NONE, &instruction_section, &system_st); add_sym("SETI", I_SETI, OC_NONE, &instruction_section, &system_st); @@ -459,8 +460,8 @@ void add_symbols( add_sym("STST", I_STST, OC_1GEN, &instruction_section, &system_st); add_sym("SUBD", I_SUBD, OC_FPPGENAC, &instruction_section, &system_st); add_sym("SUBF", I_SUBF, OC_FPPGENAC, &instruction_section, &system_st); - add_sym("TSTD", I_TSTD, OC_1GEN, &instruction_section, &system_st); - add_sym("TSTF", I_TSTF, OC_1GEN, &instruction_section, &system_st); + add_sym("TSTD", I_TSTD, OC_FPPDST, &instruction_section, &system_st); + add_sym("TSTF", I_TSTF, OC_FPPDST, &instruction_section, &system_st); /* FIXME: The CIS instructions are missing! */ diff --git a/symbols.h b/symbols.h index 0003a2d..926fd44 100644 --- a/symbols.h +++ b/symbols.h @@ -283,6 +283,10 @@ enum operand_codes { OC_MASK = 0xff00, /* FPP (gen, floating ac 0-3) */ OC_FPPACGEN = 0x0a00, /* FPP (floating ac 0-3, gen) */ + OC_FPPSRC = 0x0b00, + /* FPP fp source: immediate or gen */ + OC_FPPDST = OC_1GEN, + /* FPP general destination */ OC__LAST = 0xff00 }; diff --git a/tests/test-float.lst.ok b/tests/test-float.lst.ok index b949cd6..e46b392 100644 --- a/tests/test-float.lst.ok +++ b/tests/test-float.lst.ok @@ -121,16 +121,45 @@ 99 000340 077777 177777 177777 .FLT4 170141183460469230564930741053754966016 ; 2**127-(2**70-2**64+2**62+2) 000346 177777 100 - 101 .end - 101 + 101 ; Several ways to define a name for the fpp registers + 102 ; TODO: change symbol table to show % sign + 103 + 104 000000 ac0 = r0 + 105 000001 ac1 = %1 + 106 000002 f2 = %2 + 107 + 108 000350 171003 mulf r3,ac0 + 109 000352 171102 mulf r2,ac1 + 110 000354 172227 041040 ADDF #^O41040,F2 + 111 000360 172127 040200 addf #1,ac1 + 112 + 113 000364 171003 mulf r3,ac0 + 114 000366 171102 mulf r2,ac1 + 115 000370 172227 041040 addf #^O41040,F2 ; taken literally + 116 000374 172127 040200 addf #1,ac1 ; as float + 117 000400 172127 040200 addf #1.,ac1 ; as float + 118 000404 172127 000001 addf #^D1,ac1 ; literally + 119 000410 172127 000002 addf #<1+1>,ac1 ; literally + 120 000414 172127 040300 addf #1.5,ac1 ; as float + 121 000420 172127 140263 addd #-1.4,ac1 ; as float + 122 + 123 ; TODO: let parser check for junk at end of line + 124 000424 170627 000002 absf #2.5 ; bad: operand is destination + 125 000430 170527 000002 tstd #2.5 ; bad: operand is considered FDST by the arch handbook + 126 000434 174027 000002 stf ac0,#2.5 ; bad: junk at end of line + 127 000440 174027 000002 stf ac0,#2 ; doesn't makes sense but MACRO11 allows it + 128 + 129 + 130 .end + 130 Symbol table -. ******R 001 +. ******R 001 AC0 =000000 AC1 =000001 F2 =000002 Program sections: . ABS. 000000 000 (RW,I,GBL,ABS,OVR,NOSAV) - 000350 001 (RW,I,LCL,REL,CON,NOSAV) + 000444 001 (RW,I,LCL,REL,CON,NOSAV) diff --git a/tests/test-float.mac b/tests/test-float.mac index 52aff29..a90b971 100644 --- a/tests/test-float.mac +++ b/tests/test-float.mac @@ -98,4 +98,33 @@ .FLT4 170141183460469230564930741053754966015 ; 2**127-(2**70-2**64+2**62+1) .FLT4 170141183460469230564930741053754966016 ; 2**127-(2**70-2**64+2**62+2) + ; Several ways to define a name for the fpp registers + ; TODO: change symbol table to show % sign + +ac0 = r0 +ac1 = %1 +f2 = %2 + + mulf r3,ac0 + mulf r2,ac1 + ADDF #^O41040,F2 + addf #1,ac1 + + mulf r3,ac0 + mulf r2,ac1 + addf #^O41040,F2 ; taken literally + addf #1,ac1 ; as float + addf #1.,ac1 ; as float + addf #^D1,ac1 ; literally + addf #<1+1>,ac1 ; literally + addf #1.5,ac1 ; as float + addd #-1.4,ac1 ; as float + + ; TODO: let parser check for junk at end of line + absf #2.5 ; bad: operand is destination + tstd #2.5 ; bad: operand is considered FDST by the arch handbook + stf ac0,#2.5 ; bad: junk at end of line + stf ac0,#2 ; doesn't makes sense but MACRO11 allows it + + .end