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