1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
#include "all.h"
char *gasloc, *gassym;
void
gasemitdat(Dat *d, FILE *f)
{
static int aligned;
static char *dtoa[] = {
[DAlign] = ".balign",
[DB] = "\t.byte",
[DH] = "\t.short",
[DW] = "\t.int",
[DL] = "\t.quad"
};
char *p;
switch (d->type) {
case DStart:
aligned = 0;
if (d->u.str) {
fprintf(f, ".section %s\n", d->u.str);
} else {
fprintf(f, ".data\n");
}
break;
case DEnd:
break;
case DName:
if (!aligned)
fprintf(f, ".balign 8\n");
p = d->u.str[0] == '"' ? "" : gassym;
if (d->export)
fprintf(f, ".globl %s%s\n", p, d->u.str);
fprintf(f, "%s%s:\n", p, d->u.str);
break;
case DZ:
fprintf(f, "\t.fill %"PRId64",1,0\n", d->u.num);
break;
default:
if (d->type == DAlign)
aligned = 1;
if (d->isstr) {
if (d->type != DB)
err("strings only supported for 'b' currently");
fprintf(f, "\t.ascii %s\n", d->u.str);
}
else if (d->isref) {
p = d->u.ref.nam[0] == '"' ? "" : gassym;
fprintf(f, "%s %s%s%+"PRId64"\n",
dtoa[d->type], p, d->u.ref.nam,
d->u.ref.off);
}
else {
fprintf(f, "%s %"PRId64"\n",
dtoa[d->type], d->u.num);
}
break;
}
}
typedef struct Asmbits Asmbits;
struct Asmbits {
char bits[16];
int size;
Asmbits *link;
};
static Asmbits *stash;
int
gasstash(void *bits, int size)
{
Asmbits **pb, *b;
int i;
assert(size == 4 || size == 8 || size == 16);
for (pb=&stash, i=0; (b=*pb); pb=&b->link, i++)
if (size <= b->size)
if (memcmp(bits, b->bits, size) == 0)
return i;
b = emalloc(sizeof *b);
memcpy(b->bits, bits, size);
b->size = size;
b->link = 0;
*pb = b;
return i;
}
void
gasemitfin(FILE *f)
{
Asmbits *b;
char *p;
int sz, i;
double d;
if (!stash)
return;
fprintf(f, "/* floating point constants */\n.data\n");
for (sz=16; sz>=4; sz/=2)
for (b=stash, i=0; b; b=b->link, i++) {
if (b->size == sz) {
fprintf(f,
".balign %d\n"
"%sfp%d:",
sz, gasloc, i
);
for (p=b->bits; p<&b->bits[sz]; p+=4)
fprintf(f, "\n\t.int %"PRId32,
*(int32_t *)p);
if (sz <= 8) {
if (sz == 4)
d = *(float *)b->bits;
else
d = *(double *)b->bits;
fprintf(f, " /* %f */\n", d);
} else
fprintf(f, "\n");
}
}
while ((b=stash)) {
stash = b->link;
free(b);
}
}
|