Add the .dataf4 and .dataf8 directives to the assembler --- manually converting

floats and doubles to bytes is not fun. It might even work!
This commit is contained in:
David Given 2018-09-10 22:56:18 +02:00
parent 53f7de794a
commit a1747ac916
12 changed files with 84 additions and 9 deletions

View file

@ -28,9 +28,8 @@ toobig:
jr ra jr ra
nop nop
/* 2147483648 as a double. */
.sect .rom .sect .rom
.define .fd_80000000 .define .fd_80000000
.fd_80000000: .fd_80000000:
.data4 0, 0x41e00000 .dataf8 2147483648.0

View file

@ -31,8 +31,7 @@ toobig:
jr ra jr ra
nop nop
/* 2147483648 as a float. */
.sect .rom .sect .rom
.ff_80000000: .ff_80000000:
.data4 0x4f000000 .dataf4 2147483648.0

View file

@ -20,7 +20,6 @@ nonnegative:
jr ra jr ra
nop nop
/* 4294967296 as a double. */
.sect .rom .sect .rom
.fd_100000000: .fd_100000000:
.data4 0, 0x41f00000 .dataf8 4294967296.0

View file

@ -23,4 +23,4 @@ nonnegative:
/* 4294967296 as a float. */ /* 4294967296 as a float. */
.sect .rom .sect .rom
.fs_100000000: .fs_100000000:
.data4 0x4f800000 .dataf4 4294967296.0

View file

@ -12,6 +12,7 @@
#define WORDS_REVERSED #define WORDS_REVERSED
#define LISTING #define LISTING
#define RELOCATION #define RELOCATION
#define PDPFLOAT
#undef ISALPHA #undef ISALPHA
#define ISALPHA(c) (isalpha(c) || c == '_' || c == '.' || c == '~') #define ISALPHA(c) (isalpha(c) || c == '_' || c == '.' || c == '~')
#undef ISALNUM #undef ISALNUM

View file

@ -44,6 +44,7 @@ definerule("build_as",
deps = { deps = {
"h+emheaders", "h+emheaders",
"modules/src/object+lib", "modules/src/object+lib",
"modules/src/flt_arith+lib",
archlib, archlib,
yaccfiles, yaccfiles,
e.deps e.deps

View file

@ -153,6 +153,7 @@ void emit1(int);
void emit2(int); void emit2(int);
void emit4(long); void emit4(long);
void emitx(valu_t, int); void emitx(valu_t, int);
void emitf(int size);
void emitstr(int); void emitstr(int);
void ffreopen(char *, FILE *); void ffreopen(char *, FILE *);
FILE *ffcreat(char *); FILE *ffcreat(char *);

View file

@ -43,9 +43,11 @@ static item_t *last_it, *o_it;
%token NUMBER2 %token NUMBER2
%token NUMBER3 %token NUMBER3
%token <y_valu> NUMBER %token <y_valu> NUMBER
%token NUMBERF
%token DOT %token DOT
%token EXTERN %token EXTERN
%token <y_word> DATA %token <y_word> DATA
%token <y_word> DATAF
%token <y_word> ASCII %token <y_word> ASCII
%token SECTION %token SECTION
%token COMMON %token COMMON
@ -249,6 +251,7 @@ operation
DOTSCT->s_zero += $2; DOTSCT->s_zero += $2;
} }
| DATA datalist | DATA datalist
| DATAF dataflist
| ASCII STRING | ASCII STRING
{ emitstr($1);} { emitstr($1);}
; ;
@ -276,6 +279,18 @@ datalist
emitx($3.val, (int)$<y_word>0); emitx($3.val, (int)$<y_word>0);
} }
; ;
dataflist
: NUMBERF
{
emitf((int)$<y_word>0);
}
| dataflist ',' NUMBERF
{
emitf((int)$<y_word>3);
}
;
expr : error expr : error
{ serror("expr syntax err"); { serror("expr syntax err");
$$.val = 0; $$.typ = S_UND; $$.val = 0; $$.typ = S_UND;

View file

@ -29,6 +29,8 @@ item_t keytab[] = {
0, DATA, RELO1, ".data1", 0, DATA, RELO1, ".data1",
0, DATA, RELO2, ".data2", 0, DATA, RELO2, ".data2",
0, DATA, RELO4, ".data4", 0, DATA, RELO4, ".data4",
0, DATAF, 4, ".dataf4",
0, DATAF, 8, ".dataf8",
0, ASCII, 0, ".ascii", 0, ASCII, 0, ".ascii",
0, ASCII, 1, ".asciz", 0, ASCII, 1, ".asciz",
0, ALIGN, 0, ".align", 0, ALIGN, 0, ".align",

View file

@ -395,10 +395,12 @@ static int innumber(int c)
{ {
char* p; char* p;
int radix; int radix;
static char num[20 + 1]; static char num[40 + 1];
p = num; p = num;
radix = 20; radix = 40;
if (c == '.')
goto floatconstant;
do do
{ {
if (--radix < 0) if (--radix < 0)
@ -407,6 +409,8 @@ static int innumber(int c)
c += ('a' - 'A'); c += ('a' - 'A');
*p++ = c; *p++ = c;
c = nextchar(); c = nextchar();
if (c == '.')
goto floatconstant;
} while (isalnum(c)); } while (isalnum(c));
peekc = c; peekc = c;
*p = '\0'; *p = '\0';
@ -441,6 +445,22 @@ static int innumber(int c)
yylval.y_valu = yylval.y_valu * radix + c; yylval.y_valu = yylval.y_valu * radix + c;
} }
return (NUMBER); return (NUMBER);
floatconstant:
do
{
if (--radix < 0)
fatal("number too long");
if (isupper(c))
c += ('a' - 'A');
*p++ = c;
c = nextchar();
} while (isdigit(c) || (c == '.') || (c == 'E') || (c == '+') || (c == '-'));
*p = '\0';
stringbuf = strdup(num);
stringlen = p - num;
return NUMBERF;
} }
static int instring(int termc) static int instring(int termc)

View file

@ -346,6 +346,34 @@ void emitstr(int zero)
emit1(0); emit1(0);
} }
#define CODE_EXPANDER
#if !defined IEEEFLOAT && !defined PDPFLOAT
#define IEEEFLOAT
#endif
#if defined WORDS_REVERSED
#define FL_MSL_AT_LOW_ADDRESS 1
#define FL_MSW_AT_LOW_ADDRESS 1
#else
#define FL_MSL_AT_LOW_ADDRESS 0
#define FL_MSW_AT_LOW_ADDRESS 0
#endif
#if defined BYTES_REVERSED
#define FL_MSB_AT_LOW_ADDRESS 1
#else
#define FL_MSB_AT_LOW_ADDRESS 0
#endif
#define gen1 emit1
#include <con_float>
void emitf(int size)
{
con_float(stringbuf, size);
}
/* ---------- Error checked file I/O ---------- */ /* ---------- Error checked file I/O ---------- */
void ffreopen(char* s, FILE* f) void ffreopen(char* s, FILE* f)

View file

@ -206,6 +206,16 @@ This is not followed by automatic alignment.
.Pu ".data4 \fIexpression [, expression]*\fP" .Pu ".data4 \fIexpression [, expression]*\fP"
Initialize a sequence of longs (4-byte values). Initialize a sequence of longs (4-byte values).
This is not followed by automatic alignment. This is not followed by automatic alignment.
.Pu ".dataf4 \fIliteralfloat [, literalfloat]*\fP"
Initialize a sequence of floats (4-byte values).
The values must be literal floating point constants containing
a dot character.
This is not followed by automatic alignment.
.Pu ".dataf8 \fIliteralfloat [, literalfloat]*\fP"
Initialize a sequence of doubles (8-byte values).
The values must be literal floating point constants containing
a dot character.
This is not followed by automatic alignment.
.Pu ".ascii \fIstring\fP" .Pu ".ascii \fIstring\fP"
Initialize a sequence of bytes with the value of the bytes in Initialize a sequence of bytes with the value of the bytes in
the string. the string.