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