Pristine Ack-5.5
[Ack-5.5.git] / mach / arm / ncg / mach.c
1 /* mach.c file for ARM backend */
2
3
4 #define MAXREGVARS      4               /* Max num of register variables*/
5
6 struct reg_stuff
7 {
8     char *name;
9     long offset;
10 }
11 reg [MAXREGVARS];                       /* array of reg var details     */
12
13 char regnames[6*MAXREGVARS];            /* comma-delimited list of regs */
14 int  n_regs;                            /* current number of reg vars   */
15
16 char *segname[] = {
17         ".sect .text",
18         ".sect .data",
19         ".sect .data",
20         ".sect .bss"
21 };
22
23 con_part(sz, w)
24         register int    sz;
25         word            w;
26 {
27         while (part_size % sz) part_size++;
28
29         if (part_size == TEM_WSIZE)
30                 part_flush();
31         if (sz == 1 || sz == 2) {
32                 w &= (sz == 1 ? 0xFF : 0xFFFF);
33                 w <<= 8 * part_size;
34                 part_word |= w;
35         } else {
36                 assert(sz == 4);
37                 part_word = w;
38         }
39         part_size += sz;
40 }
41
42 con_mult(sz)
43         word    sz;
44 {
45         if (sz != 4)
46                 fatal("bad icon/ucon size");
47         fprintf(codefile,".long\t%s\n",str);
48 }
49
50
51 regscore (offset, size, type, score, totype)
52 long offset;
53 {
54     if (size > 4)                       /* only consider register-sized */
55         return -1;                      /* variables                    */
56
57     if (score < 2) return -1;
58
59     /* give greater preference to locals */
60     if (offset >= 0) score *= 4; else score *= 8;
61
62     return score;
63 }
64
65
66 i_regsave()
67 {
68     n_regs = 0;
69     *regnames = '\0';
70 }
71
72
73 regsave(name, offset, size)
74 char *name;
75 long offset;
76 {
77
78     if (n_regs > 0)                     /* if its not the first item    */
79         strcat(regnames, ",");          /* prefix it with a comma       */
80     strcat(regnames, name);             /* add to list of names to save */
81
82     reg[n_regs].name = name;            /* and add to array of reg vars */
83     reg[n_regs++].offset = offset;
84 }
85
86
87 f_regsave()
88 {
89     int i;
90     long n;
91     char *q;
92
93     if (n_regs > 0)
94         fprintf(codefile, "STMFD R12<,{%s}\n", regnames);
95
96     for (i = 0; i < n_regs; i++) {      /* load their new values        */
97         n = reg[i].offset;
98         q = reg[i].name;
99     if (n > 0)                          /* only proc parameters         */
100             fprintf(codefile, "LDR %s,[R13,#%ld]\n", q, n);
101     }
102 }
103
104
105 regreturn()
106 {
107       if (n_regs > 0)
108         fprintf(codefile, "LDMFD R12<,{%s}\n", regnames);
109 }
110
111 mes(type) word type ; {
112         int argt ;
113
114         switch ( (int)type ) {
115         case ms_ext :
116                 for (;;) {
117                         switch ( argt=getarg(
118                             ptyp(sp_cend)|ptyp(sp_pnam)|sym_ptyp) ) {
119                         case sp_cend :
120                                 return ;
121                         default:
122                                 strarg(argt) ;
123                                 fprintf(codefile,".define %s\n",argstr) ;
124                                 break ;
125                         }
126                 }
127         default :
128                 while ( getarg(any_ptyp) != sp_cend ) ;
129                 break ;
130         }
131 }
132
133 prolog(nlocals) full nlocals;
134 {
135         fprintf(codefile, "STMFD R12<,{R13,R14}\n");
136         fprintf(codefile, "MOV R13,R12\n");
137         if (nlocals)
138                 fprintf(codefile, "SUB R12,R12,#%d\n", nlocals);
139         return;
140 }
141
142 #define CODE_GENERATOR
143 #define IEEEFLOAT
144 #define FL_MSL_AT_LOW_ADDRESS   0
145 #define FL_MSW_AT_LOW_ADDRESS   0
146 #define FL_MSB_AT_LOW_ADDRESS   0
147 #include <con_float>
148