doc: minor fixes
[qbe.git] / gas.c
blobe67043bd446c58df4a8b9508854d055b57348650
1 #include "all.h"
4 char *gasloc, *gassym;
6 void
7 gasemitlnk(char *n, Lnk *l, char *s, FILE *f)
9 char *p;
11 if (l->sec) {
12 fprintf(f, ".section %s", l->sec);
13 if (l->secf)
14 fprintf(f, ", %s", l->secf);
15 } else {
16 fputs(s, f);
18 fputc('\n', f);
19 if (l->align)
20 fprintf(f, ".balign %d\n", l->align);
21 p = n[0] == '"' ? "" : gassym;
22 if (l->export)
23 fprintf(f, ".globl %s%s\n", p, n);
24 fprintf(f, "%s%s:\n", p, n);
27 void
28 gasemitdat(Dat *d, FILE *f)
30 static char *dtoa[] = {
31 [DB] = "\t.byte",
32 [DH] = "\t.short",
33 [DW] = "\t.int",
34 [DL] = "\t.quad"
36 static int64_t zero;
37 char *p;
39 switch (d->type) {
40 case DStart:
41 zero = 0;
42 break;
43 case DEnd:
44 if (zero != -1) {
45 gasemitlnk(d->name, d->lnk, ".bss", f);
46 fprintf(f, "\t.fill %"PRId64",1,0\n", zero);
48 break;
49 case DZ:
50 if (zero != -1)
51 zero += d->u.num;
52 else
53 fprintf(f, "\t.fill %"PRId64",1,0\n", d->u.num);
54 break;
55 default:
56 if (zero != -1) {
57 gasemitlnk(d->name, d->lnk, ".data", f);
58 if (zero > 0)
59 fprintf(f, "\t.fill %"PRId64",1,0\n", zero);
60 zero = -1;
62 if (d->isstr) {
63 if (d->type != DB)
64 err("strings only supported for 'b' currently");
65 fprintf(f, "\t.ascii %s\n", d->u.str);
67 else if (d->isref) {
68 p = d->u.ref.name[0] == '"' ? "" : gassym;
69 fprintf(f, "%s %s%s%+"PRId64"\n",
70 dtoa[d->type], p, d->u.ref.name,
71 d->u.ref.off);
73 else {
74 fprintf(f, "%s %"PRId64"\n",
75 dtoa[d->type], d->u.num);
77 break;
81 typedef struct Asmbits Asmbits;
83 struct Asmbits {
84 char bits[16];
85 int size;
86 Asmbits *link;
89 static Asmbits *stash;
91 int
92 gasstash(void *bits, int size)
94 Asmbits **pb, *b;
95 int i;
97 assert(size == 4 || size == 8 || size == 16);
98 for (pb=&stash, i=0; (b=*pb); pb=&b->link, i++)
99 if (size <= b->size)
100 if (memcmp(bits, b->bits, size) == 0)
101 return i;
102 b = emalloc(sizeof *b);
103 memcpy(b->bits, bits, size);
104 b->size = size;
105 b->link = 0;
106 *pb = b;
107 return i;
110 void
111 gasemitfin(FILE *f)
113 Asmbits *b;
114 char *p;
115 int sz, i;
116 double d;
118 if (!stash)
119 return;
120 fprintf(f, "/* floating point constants */\n.data\n");
121 for (sz=16; sz>=4; sz/=2)
122 for (b=stash, i=0; b; b=b->link, i++) {
123 if (b->size == sz) {
124 fprintf(f,
125 ".balign %d\n"
126 "%sfp%d:",
127 sz, gasloc, i
129 for (p=b->bits; p<&b->bits[sz]; p+=4)
130 fprintf(f, "\n\t.int %"PRId32,
131 *(int32_t *)p);
132 if (sz <= 8) {
133 if (sz == 4)
134 d = *(float *)b->bits;
135 else
136 d = *(double *)b->bits;
137 fprintf(f, " /* %f */\n", d);
138 } else
139 fprintf(f, "\n");
142 while ((b=stash)) {
143 stash = b->link;
144 free(b);