Began adding the code generation framework.
[fw/sdcc] / src / izt / i186.c
1 /** @file izt/i186.c
2     i186 specific general functions.
3 */
4 #include "izt.h"
5
6 static REG _i186_regs[] = {
7     { 1, REG_ID_CL, "cl", 0, { REG_ID_CX, REG_ID_NONE, REG_ID_NONE } },
8     { 1, REG_ID_CH, "ch", 0, { REG_ID_CX, REG_ID_NONE, REG_ID_NONE } },
9     { 1, REG_ID_DL, "dl", 0, { REG_ID_DX, REG_ID_NONE, REG_ID_NONE } },
10     { 1, REG_ID_DH, "dh", 0, { REG_ID_DX, REG_ID_NONE, REG_ID_NONE } },
11     { 2, REG_ID_CX, "cx", 0, { REG_ID_CL, REG_ID_CH, REG_ID_NONE } },
12     { 2, REG_ID_DX, "dx", 0, { REG_ID_DL, REG_ID_DH, REG_ID_NONE } },
13     { 0, REG_ID_NONE,"??",  0, { REG_ID_NONE, REG_ID_NONE, REG_ID_NONE } }
14 };
15
16 static IZT_PORT _i186_port = {
17     _i186_regs
18 };
19
20 static char _defaultRules[] =
21 {
22     //#include "peeph.rul"
23 };
24
25 /* list of key words used by i186 */
26 static char *_i186_keywords[] =     {
27     NULL
28 };
29
30 // PENDING: A default set of mappings to make asm.c happy.
31 static const ASM_MAPPING _asxxxx_z80_mapping[] = {
32     /* We want to prepend the _ */
33     { "area", ".area _%s" },
34     { "areacode", ".area _%s" },
35     { "areadata", ".area _%s" },
36     { "areahome", ".area _%s" },
37     { "*ixx", "%d(ix)" },
38     { "*iyx", "%d(iy)" },
39     { "*hl", "(hl)" },
40     { "di", "di" },
41     { "ldahli", 
42                 "ld a,(hl)\n"
43                 "\tinc\thl" },
44     { "ldahlsp", 
45                 "ld hl,#%d\n"
46                 "\tadd\thl,sp" },
47     { "ldaspsp", 
48                 "ld hl,#%d\n"
49                 "\tadd\thl,sp\n"
50                 "\tld\tsp,hl" },
51     { "*pair", "(%s)" },
52     { "shortjp", "jp" },
53     { "enter", 
54                 "push\tix\n"
55                 "\tld\tix,#0\n"
56                 "\tadd\tix,sp" },
57     { "enterx", 
58                 "push\tix\n"
59                 "\tld\tix,#0\n"
60                 "\tadd\tix,sp\n"
61                 "\tld\thl,#-%d\n"
62                 "\tadd\thl,sp\n"
63                 "\tld\tsp,hl" },
64     { "leave", 
65                 "pop\tix\n"
66     },
67     { "leavex", 
68                 "ld sp,ix\n"
69                 "\tpop\tix\n"
70     },
71     { "pusha", 
72                 "push af\n"
73                 "\tpush\tbc\n"
74                 "\tpush\tde\n"
75                 "\tpush\thl"
76     },
77     { "adjustsp", "lda sp,-%d(sp)" },
78     { NULL, NULL }
79 };
80
81 static const ASM_MAPPINGS _asxxxx_z80 = {
82     &asm_asxxxx_mapping,
83     _asxxxx_z80_mapping
84 };
85
86 static void _i186_init(void)
87 {
88     asm_addTree(&asm_asxxxx_mapping);
89     asm_addTree(&_asxxxx_z80);
90     izt_init(&_i186_port);
91 }
92
93 static void _i186_reset_regparm()
94 {
95 }
96
97 static int _i186_regparm( sym_link *l)
98 {
99     // PENDING: No register parameters.
100     return 0;
101 }
102
103 static bool _i186_parseOptions(int *pargc, char **argv, int *i)
104 {
105     /* TODO: allow port-specific command line options to specify
106      * segment names here.
107      */
108     return FALSE;
109 }
110
111 static void _i186_finaliseOptions(void)
112 {
113     // No options
114 }
115
116 static void _i186_setDefaultOptions(void)
117 {
118     // No options
119 }
120
121 static const char *_i186_getRegName(struct regs *reg)
122 {
123     if (reg)
124         return reg->name;
125     wassert(0);
126     return "err";
127 }
128
129 static void _i186_genAssemblerPreamble(FILE *of)
130 {
131     // PENDING
132 }
133
134 /* Generate interrupt vector table. */
135 static int _i186_genIVT(FILE *of, symbol **interrupts, int maxInterrupts)
136 {
137     // PENDING
138     return 0;
139 }
140
141 /** $1 is always the basename.
142     $2 is always the output file.
143     $3 varies
144     $l is the list of extra options that should be there somewhere...
145     MUST be terminated with a NULL.
146 */
147 // PENDING
148 static const char *_linkCmd[] = {
149     "aslink", "-nf", "$1", NULL
150 };
151
152 // PENDING
153 static const char *_asmCmd[] = {
154  "gpasm", NULL, NULL, NULL
155 };
156
157 void i186_assignRegisters (eBBlock **ebbs, int count)
158 {
159 }
160
161 /* Globals */
162 PORT i186_port = {
163     "i186",
164     "Intel 8086/80186",         /* Target name */
165     {
166         FALSE,                  /* Emit glue around main */
167         MODEL_SMALL,
168         MODEL_SMALL
169     },
170     {   
171         _asmCmd,
172         NULL,
173         NULL,
174         0
175     },
176     {
177         _linkCmd,
178         NULL,
179         ".o"
180     },
181     {
182         _defaultRules
183     },
184     {
185         /* Sizes: char, short, int, long, ptr, fptr, gptr, bit, float, max */
186         1, 2, 2, 4, 2, 2, 2, 1, 4, 4
187     },
188     {
189         "XSEG    (XDATA)",
190         "STACK   (DATA)",
191         "CSEG    (CODE)",
192         "DSEG    (DATA)",
193         "ISEG    (DATA)",
194         "XSEG    (XDATA)",
195         "BSEG    (BIT)",
196         "RSEG    (DATA)",
197         "GSINIT  (CODE)",
198         "OSEG    (OVR,DATA)",
199         "GSFINAL (CODE)",
200         "HOME    (CODE)",
201         NULL,
202         NULL,
203         1
204     },
205     { 
206         +1, 1, 4, 1, 1, 0
207     },
208     /* i186 has an 16 bit mul */
209     {
210         2, 0
211     },
212     "_",
213     _i186_init,
214     _i186_parseOptions,
215     _i186_finaliseOptions,
216     _i186_setDefaultOptions,
217     izt_assignRegisters,
218     _i186_getRegName ,
219     _i186_keywords,
220     _i186_genAssemblerPreamble,
221     _i186_genIVT ,
222     _i186_reset_regparm,
223     _i186_regparm,
224     NULL,
225     FALSE,
226     0,  /* leave lt */
227     0,  /* leave gt */
228     1,  /* transform <= to ! > */
229     1,  /* transform >= to ! < */
230     1,  /* transform != to !(a == b) */
231     0   /* leave == */
232 };