struct / union in initializer, RFE #901.
[sdcc.git] / sdcc / src / z80 / main.c
blob989e09170a55e14515609262bd3490e8aeb5af70
1 /*-------------------------------------------------------------------------
2 main.c - Z80 specific definitions.
4 Michael Hope <michaelh@juju.net.nz> 2001
5 Copyright (C) 2021, Sebastian 'basxto' Riedel <sdcc@basxto.de>
7 This program is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
10 later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 In other words, you are welcome to use, share and improve this program.
22 You are forbidden to forbid anyone else to use, share and improve
23 what you give them. Help stamp out software-hoarding!
24 -------------------------------------------------------------------------*/
26 #include <sys/stat.h>
27 #include "z80.h"
28 #include "SDCCsystem.h"
29 #include "SDCCutil.h"
30 #include "SDCCargs.h"
31 #include "dbuf_string.h"
33 #define OPTION_BO "-bo"
34 #define OPTION_BA "-ba"
35 #define OPTION_CODE_SEG "--codeseg"
36 #define OPTION_CONST_SEG "--constseg"
37 #define OPTION_DATA_SEG "--dataseg"
38 #define OPTION_CALLEE_SAVES_BC "--callee-saves-bc"
39 #define OPTION_PORTMODE "--portmode="
40 #define OPTION_ASM "--asm="
41 #define OPTION_NO_STD_CRT0 "--no-std-crt0"
42 #define OPTION_RESERVE_IY "--reserve-regs-iy"
43 #define OPTION_FRAMEPOINTER "--fno-omit-frame-pointer"
44 #define OPTION_EMIT_EXTERNS "--emit-externs"
45 #define OPTION_LEGACY_BANKING "--legacy-banking"
46 #define OPTION_NMOS_Z80 "--nmos-z80"
47 #define OPTION_SDCCCALL "--sdcccall"
48 #define OPTION_ALLOW_UNDOC_INST "--allow-undocumented-instructions"
50 static char _z80_defaultRules[] = {
51 #include "peeph.rul"
52 #include "peeph-z80.rul"
55 static char _r2k_defaultRules[] = {
56 #include "peeph.rul"
57 #include "peeph-r2k.rul"
60 static char _tlcs90_defaultRules[] = {
61 #include "peeph.rul"
62 #include "peeph-tlcs90.rul"
65 static char _sm83_defaultRules[] = {
66 #include "peeph-sm83.rul"
67 #include "peeph.rul"
70 static char _ez80_z80_defaultRules[] = {
71 #include "peeph.rul"
72 #include "peeph-z80.rul"
73 #include "peeph-ez80_z80.rul"
76 static char _z80n_defaultRules[] = {
77 #include "peeph.rul"
78 #include "peeph-z80.rul"
79 #include "peeph-z80n.rul"
83 Z80_OPTS z80_opts;
85 static OPTION _z80_like_options[] = {
86 {0, OPTION_CALLEE_SAVES_BC, &z80_opts.calleeSavesBC, "Force a called function to always save BC"},
87 {0, OPTION_PORTMODE, NULL, "Determine PORT I/O mode (z80/z180)"},
88 {0, OPTION_BO, NULL, "<num> use code bank <num>"},
89 {0, OPTION_BA, NULL, "<num> use data bank <num>"},
90 {0, OPTION_ASM, NULL, "Define assembler name (rgbds/asxxxx/isas/z80asm/gas)"},
91 {0, OPTION_CODE_SEG, &options.code_seg, "<name> use this name for the code segment", CLAT_STRING},
92 {0, OPTION_CONST_SEG, &options.const_seg, "<name> use this name for the const segment", CLAT_STRING},
93 {0, OPTION_DATA_SEG, &options.data_seg, "<name> use this name for the data segment", CLAT_STRING},
94 {0, OPTION_NO_STD_CRT0, &options.no_std_crt0, "Do not link default crt0.rel"},
95 {0, OPTION_RESERVE_IY, &z80_opts.reserveIY, "Do not use IY (incompatible with --fomit-frame-pointer)"},
96 {0, OPTION_FRAMEPOINTER, &z80_opts.noOmitFramePtr, "Do not omit frame pointer"},
97 {0, OPTION_EMIT_EXTERNS, NULL, "Emit externs list in generated asm"},
98 {0, OPTION_LEGACY_BANKING, &z80_opts.legacyBanking, "Use legacy method to call banked functions"},
99 {0, OPTION_NMOS_Z80, &z80_opts.nmosZ80, "Generate workaround for NMOS Z80 when saving IFF2"},
100 {0, OPTION_SDCCCALL, &options.sdcccall, "Set ABI version for default calling convention", CLAT_INTEGER},
101 {0, NULL}
104 static OPTION _z80_options[] = {
105 {0, OPTION_CALLEE_SAVES_BC, &z80_opts.calleeSavesBC, "Force a called function to always save BC"},
106 {0, OPTION_PORTMODE, NULL, "Determine PORT I/O mode (z80/z180)"},
107 {0, OPTION_BO, NULL, "<num> use code bank <num>"},
108 {0, OPTION_BA, NULL, "<num> use data bank <num>"},
109 {0, OPTION_ASM, NULL, "Define assembler name (rgbds/asxxxx/isas/z80asm/gas)"},
110 {0, OPTION_CODE_SEG, &options.code_seg, "<name> use this name for the code segment", CLAT_STRING},
111 {0, OPTION_CONST_SEG, &options.const_seg, "<name> use this name for the const segment", CLAT_STRING},
112 {0, OPTION_DATA_SEG, &options.data_seg, "<name> use this name for the data segment", CLAT_STRING},
113 {0, OPTION_NO_STD_CRT0, &options.no_std_crt0, "Do not link default crt0.rel"},
114 {0, OPTION_RESERVE_IY, &z80_opts.reserveIY, "Do not use IY (incompatible with --fomit-frame-pointer)"},
115 {0, OPTION_FRAMEPOINTER, &z80_opts.noOmitFramePtr, "Do not omit frame pointer"},
116 {0, OPTION_EMIT_EXTERNS, NULL, "Emit externs list in generated asm"},
117 {0, OPTION_LEGACY_BANKING, &z80_opts.legacyBanking, "Use legacy method to call banked functions"},
118 {0, OPTION_NMOS_Z80, &z80_opts.nmosZ80, "Generate workaround for NMOS Z80 when saving IFF2"},
119 {0, OPTION_SDCCCALL, &options.sdcccall, "Set ABI version for default calling convention", CLAT_INTEGER},
120 {0, OPTION_ALLOW_UNDOC_INST,&options.allow_undoc_inst, "Allow use of undocumented instructions"},
121 {0, NULL}
124 static OPTION _sm83_options[] = {
125 {0, OPTION_BO, NULL, "<num> use code bank <num>"},
126 {0, OPTION_BA, NULL, "<num> use data bank <num>"},
127 {0, OPTION_ASM, NULL, "Define assembler name (rgbds/asxxxx/isas/z80asm/gas)"},
128 {0, OPTION_CALLEE_SAVES_BC, &z80_opts.calleeSavesBC, "Force a called function to always save BC"},
129 {0, OPTION_CODE_SEG, &options.code_seg, "<name> use this name for the code segment", CLAT_STRING},
130 {0, OPTION_CONST_SEG, &options.const_seg, "<name> use this name for the const segment", CLAT_STRING},
131 {0, OPTION_DATA_SEG, &options.data_seg, "<name> use this name for the data segment", CLAT_STRING},
132 {0, OPTION_NO_STD_CRT0, &options.no_std_crt0, "Do not link default crt0.rel"},
133 {0, OPTION_LEGACY_BANKING, &z80_opts.legacyBanking, "Use legacy method to call banked functions"},
134 {0, OPTION_SDCCCALL, &options.sdcccall, "Set ABI version for default calling convention", CLAT_INTEGER},
135 {0, NULL}
138 typedef enum
140 /* Must be first */
141 ASM_TYPE_ASXXXX,
142 ASM_TYPE_RGBDS,
143 ASM_TYPE_ISAS,
144 ASM_TYPE_Z80ASM,
145 ASM_TYPE_GAS
147 ASM_TYPE;
149 static struct
151 ASM_TYPE asmType;
152 // Determine if we can put parameters in registers
153 struct
155 int n;
156 struct sym_link *ftype;
157 } regparam;
161 static char *_keywords[] = {
162 "sfr",
163 "nonbanked",
164 "banked",
165 "at",
166 "_naked",
167 "critical",
168 "interrupt",
169 "z88dk_fastcall",
170 "z88dk_callee",
171 "smallc",
172 "z88dk_shortcall",
173 "z88dk_params_offset",
174 NULL
177 static char *_keywordsgb[] = {
178 "sfr",
179 "nonbanked",
180 "banked",
181 "at",
182 "_naked",
183 "critical",
184 "interrupt",
185 "z88dk_callee",
186 "smallc",
187 NULL
190 static char *_keywordstlcs90[] = {
191 "nonbanked",
192 "banked",
193 "at",
194 "_naked",
195 "critical",
196 "interrupt",
197 "z88dk_fastcall",
198 "z88dk_callee",
199 "smallc",
200 NULL
203 extern PORT z80_port;
204 extern PORT r2k_port;
205 extern PORT sm83_port;
207 #include "mappings.i"
209 static builtins _z80_builtins[] = {
210 {"__builtin_memcpy", "vg*", 3, {"vg*", "Cvg*", "Ui"}},
211 {"__builtin_strcpy", "cg*", 2, {"cg*", "Ccg*"}},
212 {"__builtin_strncpy", "cg*", 3, {"cg*", "Ccg*", "Ui"}},
213 {"__builtin_strchr", "cg*", 2, {"Ccg*", "i"}},
214 {"__builtin_memset", "vg*", 3, {"vg*", "i", "Ui"}},
215 {NULL, NULL, 0, {NULL}}
218 extern reg_info sm83_regs[];
219 extern reg_info z80_regs[];
220 extern void z80_init_asmops (void);
221 extern reg_info *regsZ80;
223 static void
224 _z80_init (void)
226 z80_opts.sub = SUB_Z80;
227 switch (_G.asmType)
229 case ASM_TYPE_GAS:
230 asm_addTree (&_gas_z80);
231 break;
232 default:
233 asm_addTree (&_asxxxx_z80);
234 break;
237 regsZ80 = z80_regs;
238 z80_init_asmops ();
241 static void
242 _z180_init (void)
244 z80_opts.sub = SUB_Z180;
245 switch (_G.asmType)
247 case ASM_TYPE_GAS:
248 asm_addTree (&_gas_z80);
249 break;
250 default:
251 asm_addTree (&_asxxxx_z80);
252 break;
255 regsZ80 = z80_regs;
256 z80_init_asmops ();
259 static void
260 _r2k_init (void)
262 z80_opts.sub = SUB_R2K;
263 asm_addTree (&_asxxxx_r2k);
265 regsZ80 = z80_regs;
266 z80_init_asmops ();
269 static void
270 _r2ka_init (void)
272 z80_opts.sub = SUB_R2KA;
273 asm_addTree (&_asxxxx_r2k);
275 regsZ80 = z80_regs;
276 z80_init_asmops ();
279 static void
280 _r3ka_init (void)
282 z80_opts.sub = SUB_R3KA;
283 asm_addTree (&_asxxxx_r2k);
285 regsZ80 = z80_regs;
286 z80_init_asmops ();
289 static void
290 _sm83_init (void)
292 z80_opts.sub = SUB_SM83;
294 regsZ80 = sm83_regs;
295 z80_init_asmops ();
298 static void
299 _tlcs90_init (void)
301 z80_opts.sub = SUB_TLCS90;
302 asm_addTree (&_asxxxx_z80);
304 regsZ80 = z80_regs;
305 z80_init_asmops ();
308 static void
309 _ez80_z80_init (void)
311 z80_opts.sub = SUB_EZ80_Z80;
312 switch (_G.asmType)
314 case ASM_TYPE_GAS:
315 asm_addTree (&_gas_z80);
316 break;
317 default:
318 asm_addTree (&_asxxxx_z80);
319 break;
322 regsZ80 = z80_regs;
323 z80_init_asmops ();
326 static void
327 _z80n_init (void)
329 z80_opts.sub = SUB_Z80N;
330 asm_addTree (&_asxxxx_z80);
332 regsZ80 = z80_regs;
333 z80_init_asmops ();
336 static void
337 _r800_init (void)
339 z80_opts.sub = SUB_R800;
340 asm_addTree (&_asxxxx_z80);
342 regsZ80 = z80_regs;
343 z80_init_asmops ();
346 static void
347 _reset_regparm (struct sym_link *ftype)
349 _G.regparam.n = 0;
350 _G.regparam.ftype = ftype;
351 if (IFFUNC_ISZ88DK_FASTCALL (ftype) && IFFUNC_HASVARARGS (ftype))
352 werror (E_Z88DK_FASTCALL_PARAMETERS);
355 static int
356 _reg_parm (sym_link *l, bool reentrant)
358 if (IFFUNC_ISZ88DK_FASTCALL (_G.regparam.ftype))
360 if (_G.regparam.n)
361 werror (E_Z88DK_FASTCALL_PARAMETERS);
362 if (getSize (l) > 4)
363 werror (E_Z88DK_FASTCALL_PARAMETER);
366 bool is_regarg = z80IsRegArg (_G.regparam.ftype, ++_G.regparam.n, 0);
368 return (is_regarg ? _G.regparam.n : 0);
371 enum
373 P_BANK = 1,
374 P_PORTMODE,
375 P_CODESEG,
376 P_CONSTSEG,
379 static int
380 do_pragma (int id, const char *name, const char *cp)
382 struct pragma_token_s token;
383 int err = 0;
384 int processed = 1;
386 init_pragma_token (&token);
388 switch (id)
390 case P_BANK:
392 struct dbuf_s buffer;
394 dbuf_init (&buffer, 128);
396 cp = get_pragma_token (cp, &token);
398 switch (token.type)
400 case TOKEN_EOL:
401 err = 1;
402 break;
404 case TOKEN_INT:
405 switch (_G.asmType)
407 case ASM_TYPE_ASXXXX:
408 dbuf_printf (&buffer, "CODE_%d", token.val.int_val);
409 break;
411 case ASM_TYPE_RGBDS:
412 dbuf_printf (&buffer, "ROMX,BANK[%d]", token.val.int_val);
413 break;
415 case ASM_TYPE_ISAS:
416 /* PENDING: what to use for ISAS? */
417 dbuf_printf (&buffer, "CODE,BANK(%d)", token.val.int_val);
418 break;
420 case ASM_TYPE_GAS:
421 dbuf_printf (&buffer, ".ovly%04x", token.val.int_val);
422 break;
424 default:
425 wassert (0);
427 break;
429 default:
431 const char *str = get_pragma_string (&token);
433 dbuf_append_str (&buffer, (0 == strcmp ("BASE", str)) ? "HOME" : str);
435 break;
438 cp = get_pragma_token (cp, &token);
439 if (TOKEN_EOL != token.type)
441 err = 1;
442 break;
445 dbuf_c_str (&buffer);
446 options.code_seg = (char *) dbuf_detach (&buffer);
448 break;
450 case P_PORTMODE:
451 { /*.p.t.20030716 - adding pragma to manipulate z80 i/o port addressing modes */
452 const char *str;
454 cp = get_pragma_token (cp, &token);
456 if (TOKEN_EOL == token.type)
458 err = 1;
459 break;
462 str = get_pragma_string (&token);
464 cp = get_pragma_token (cp, &token);
465 if (TOKEN_EOL != token.type)
467 err = 1;
468 break;
471 if (!strcmp (str, "z80"))
473 z80_opts.port_mode = 80;
475 else if (!strcmp (str, "z180"))
477 z80_opts.port_mode = 180;
479 else if (!strcmp (str, "save"))
481 z80_opts.port_back = z80_opts.port_mode;
483 else if (!strcmp (str, "restore"))
485 z80_opts.port_mode = z80_opts.port_back;
487 else
488 err = 1;
490 break;
492 case P_CODESEG:
493 case P_CONSTSEG:
495 char *segname;
497 cp = get_pragma_token (cp, &token);
498 if (token.type == TOKEN_EOL)
500 err = 1;
501 break;
504 segname = Safe_strdup (get_pragma_string (&token));
506 cp = get_pragma_token (cp, &token);
507 if (token.type != TOKEN_EOL)
509 Safe_free (segname);
510 err = 1;
511 break;
514 if (id == P_CODESEG)
516 if (options.code_seg)
517 Safe_free (options.code_seg);
518 options.code_seg = segname;
520 else
522 if (options.const_seg)
523 Safe_free (options.const_seg);
524 options.const_seg = segname;
527 break;
529 default:
530 processed = 0;
531 break;
534 get_pragma_token (cp, &token);
536 if (1 == err)
537 werror (W_BAD_PRAGMA_ARGUMENTS, name);
539 free_pragma_token (&token);
540 return processed;
543 static struct pragma_s pragma_tbl[] = {
544 {"bank", P_BANK, 0, do_pragma},
545 {"portmode", P_PORTMODE, 0, do_pragma},
546 {"codeseg", P_CODESEG, 0, do_pragma},
547 {"constseg", P_CONSTSEG, 0, do_pragma},
548 {NULL, 0, 0, NULL},
551 static int
552 _process_pragma (const char *s)
554 return process_pragma_tbl (pragma_tbl, s);
557 static const char *_sm83_rgbasmCmd[] = {
558 "rgbasm", "-o$1.rel", "$1.asm", NULL
561 static const char *_sm83_rgblinkCmd[] = {
562 "xlink", "-tg", "-n$1.sym", "-m$1.map", "-zFF", "$1.lnk", NULL
565 static void
566 _sm83_rgblink (void)
568 FILE *lnkfile;
569 struct dbuf_s lnkFileName;
570 char *buffer;
572 dbuf_init (&lnkFileName, PATH_MAX);
574 /* first we need to create the <filename>.lnk file */
575 dbuf_append_str (&lnkFileName, dstFileName);
576 dbuf_append_str (&lnkFileName, ".lk");
577 if (!(lnkfile = fopen (dbuf_c_str (&lnkFileName), "w")))
579 werror (E_OUTPUT_FILE_OPEN_ERR, dbuf_c_str (&lnkFileName), strerror (errno));
580 dbuf_destroy (&lnkFileName);
581 exit (1);
583 dbuf_destroy (&lnkFileName);
585 fprintf (lnkfile, "[Objects]\n");
587 fprintf (lnkfile, "%s.rel\n", dstFileName);
589 fputStrSet (lnkfile, relFilesSet);
591 fprintf (lnkfile, "\n[Libraries]\n");
592 /* additional libraries if any */
593 fputStrSet (lnkfile, libFilesSet);
595 fprintf (lnkfile, "\n[Output]\n" "%s.gb", dstFileName);
597 fclose (lnkfile);
599 buffer = buildCmdLine (port->linker.cmd, dstFileName, NULL, NULL, NULL, NULL);
600 /* call the linker */
601 if (sdcc_system (buffer))
603 Safe_free (buffer);
604 perror ("Cannot exec linker");
605 exit (1);
607 Safe_free (buffer);
610 static bool
611 _parseOptions (int *pargc, char **argv, int *i)
613 if (argv[*i][0] == '-')
615 if (IS_SM83 || IS_Z80)
617 if (!strncmp (argv[*i], OPTION_BO, sizeof (OPTION_BO) - 1))
619 /* ROM bank */
620 int bank = getIntArg (OPTION_BO, argv, i, *pargc);
621 struct dbuf_s buffer;
623 dbuf_init (&buffer, 16);
624 if (_G.asmType == ASM_TYPE_RGBDS)
626 dbuf_printf (&buffer, "ROMX,BANK[%u]", bank);
628 else
630 dbuf_printf (&buffer, "CODE_%u", bank);
632 dbuf_c_str (&buffer);
633 options.code_seg = (char *) dbuf_detach (&buffer);
634 return TRUE;
636 else if (!strncmp (argv[*i], OPTION_BA, sizeof (OPTION_BA) - 1))
638 /* RAM bank */
639 int bank = getIntArg (OPTION_BA, argv, i, *pargc);
640 struct dbuf_s buffer;
642 dbuf_init (&buffer, 16);
643 if (_G.asmType == ASM_TYPE_RGBDS)
645 dbuf_printf (&buffer, "SRAM,BANK[%u]", bank);
647 else
649 dbuf_printf (&buffer, "DATA_%u", bank);
651 dbuf_c_str (&buffer);
652 options.data_seg = (char *) dbuf_detach (&buffer);
653 return TRUE;
657 if (!strncmp (argv[*i], OPTION_ASM, sizeof (OPTION_ASM) - 1))
659 char *asmblr = getStringArg (OPTION_ASM, argv, i, *pargc);
661 if (!strcmp (asmblr, "rgbds"))
663 asm_addTree (&_rgbds_gb);
664 // rgbds doesn't understand that
665 options.noOptsdccInAsm = true;
667 sm83_port.assembler.cmd = _sm83_rgbasmCmd;
668 sm83_port.linker.cmd = _sm83_rgblinkCmd;
669 sm83_port.linker.do_link = _sm83_rgblink;
671 if(!(options.code_seg && strcmp(options.code_seg, CODE_NAME)))
673 if (options.code_seg)
674 Safe_free (options.code_seg);
675 options.code_seg = Safe_strdup ("ROMX");
677 if(!(options.data_seg && strcmp(options.data_seg, DATA_NAME)))
679 if (options.data_seg)
680 Safe_free (options.data_seg);
681 options.data_seg = Safe_strdup ("WRAMX");
684 _G.asmType = ASM_TYPE_RGBDS;
685 return TRUE;
687 else if (!strcmp (asmblr, "asxxxx"))
689 _G.asmType = ASM_TYPE_ASXXXX;
690 return TRUE;
692 else if (!strcmp (asmblr, "isas"))
694 asm_addTree (&_isas_gb);
695 /* Munge the function prefix */
696 sm83_port.fun_prefix = "";
697 _G.asmType = ASM_TYPE_ISAS;
698 return TRUE;
700 else if (!strcmp (asmblr, "z80asm"))
702 port->assembler.externGlobal = TRUE;
703 asm_addTree (&_z80asm_z80);
704 _G.asmType = ASM_TYPE_ISAS;
705 return TRUE;
707 else if (!strcmp (asmblr, "gas"))
709 port->assembler.externGlobal = TRUE;
710 asm_addTree (&_gas_z80);
711 _G.asmType = ASM_TYPE_GAS;
712 return TRUE;
715 else if (!strncmp (argv[*i], OPTION_PORTMODE, sizeof (OPTION_PORTMODE) - 1))
717 char *portmode = getStringArg (OPTION_ASM, argv, i, *pargc);
719 if (!strcmp (portmode, "z80"))
721 z80_opts.port_mode = 80;
722 return TRUE;
724 else if (!strcmp (portmode, "z180"))
726 z80_opts.port_mode = 180;
727 return TRUE;
730 else if (!strncmp (argv[*i], OPTION_EMIT_EXTERNS, sizeof (OPTION_EMIT_EXTERNS) - 1))
732 port->assembler.externGlobal = 1;
733 return true;
736 return FALSE;
739 static void
740 _setValues (void)
742 const char *s;
743 struct dbuf_s dbuf;
745 if (options.nostdlib == FALSE)
747 const char *s;
748 char *path;
749 struct dbuf_s dbuf;
751 dbuf_init (&dbuf, PATH_MAX);
753 for (s = setFirstItem (libDirsSet); s != NULL; s = setNextItem (libDirsSet))
755 path = buildCmdLine2 ("-k\"%s" DIR_SEPARATOR_STRING "{port}\" ", s);
756 dbuf_append_str (&dbuf, path);
757 Safe_free (path);
759 path = buildCmdLine2 ("-l\"{port}.lib\"", s);
760 dbuf_append_str (&dbuf, path);
761 Safe_free (path);
763 setMainValue ("z80libspec", dbuf_c_str (&dbuf));
764 dbuf_destroy (&dbuf);
766 for (s = setFirstItem (libDirsSet); s != NULL; s = setNextItem (libDirsSet))
768 struct stat stat_buf;
770 path = buildCmdLine2 ("%s" DIR_SEPARATOR_STRING "{port}" DIR_SEPARATOR_STRING "crt0{objext}", s);
771 if (stat (path, &stat_buf) == 0)
773 Safe_free (path);
774 break;
776 else
777 Safe_free (path);
780 if (s == NULL)
781 setMainValue ("z80crt0", "\"crt0{objext}\"");
782 else
784 struct dbuf_s dbuf;
786 dbuf_init (&dbuf, 128);
787 dbuf_printf (&dbuf, "\"%s\"", path);
788 setMainValue ("z80crt0", dbuf_c_str (&dbuf));
789 dbuf_destroy (&dbuf);
792 else
794 setMainValue ("z80libspec", "");
795 setMainValue ("z80crt0", "");
798 setMainValue ("z80extralibfiles", (s = joinStrSet (libFilesSet)));
799 Safe_free ((void *) s);
800 setMainValue ("z80extralibpaths", (s = joinStrSet (libPathsSet)));
801 Safe_free ((void *) s);
803 if (IS_SM83)
805 setMainValue ("z80outputtypeflag", "-Z");
806 setMainValue ("z80outext", ".gb");
808 else
810 setMainValue ("z80outputtypeflag", "-i");
811 setMainValue ("z80outext", ".ihx");
814 setMainValue ("stdobjdstfilename", "{dstfilename}{objext}");
815 setMainValue ("stdlinkdstfilename", "{dstfilename}{z80outext}");
817 setMainValue ("z80extraobj", (s = joinStrSet (relFilesSet)));
818 Safe_free ((void *) s);
820 dbuf_init (&dbuf, 128);
821 dbuf_printf (&dbuf, "-b_CODE=0x%04X -b_DATA=0x%04X", options.code_loc, options.data_loc);
822 setMainValue ("z80bases", dbuf_c_str (&dbuf));
823 dbuf_destroy (&dbuf);
826 static void
827 _finaliseOptions (void)
829 port->mem.default_local_map = data;
830 port->mem.default_globl_map = data;
831 if (IS_SM83)
832 switch (_G.asmType)
834 case ASM_TYPE_ASXXXX:
835 asm_addTree (&_asxxxx_gb);
836 break;
837 case ASM_TYPE_GAS:
838 asm_addTree (&_gas_gb);
839 break;
840 case ASM_TYPE_ISAS:
841 case ASM_TYPE_RGBDS:
842 case ASM_TYPE_Z80ASM:
843 break;
846 if (IY_RESERVED)
847 port->num_regs -= 2;
849 _setValues ();
852 static void
853 _setDefaultOptions (void)
855 options.nopeep = 0;
856 options.stackAuto = 1;
857 /* first the options part */
858 options.intlong_rent = 1;
859 options.float_rent = 1;
860 options.noRegParams = 0;
861 /* Default code and data locations. */
862 options.code_loc = 0x200;
863 options.allow_undoc_inst = false;
865 if (IS_SM83)
866 options.data_loc = 0xc000;
867 else if (IS_RAB) // Match default crt0
868 options.data_loc = 0xa000;
869 else
870 options.data_loc = 0x8000;
872 options.out_fmt = 'i'; /* Default output format is ihx */
875 #if 0
876 /* Mangling format:
877 _fun_policy_params
878 where:
879 policy is the function policy
880 params is the parameter format
882 policy format:
884 where:
885 r is 'r' for reentrant, 's' for static functions
886 s is 'c' for callee saves, 'r' for caller saves
887 f is 'f' for profiling on, 'x' for profiling off
888 examples:
889 rr - reentrant, caller saves
890 params format:
891 A combination of register short names and s to signify stack variables.
892 examples:
893 bds - first two args appear in BC and DE, the rest on the stack
894 s - all arguments are on the stack.
896 static const char *
897 _mangleSupportFunctionName (const char *original)
899 struct dbuf_s dbuf;
901 if (strstr (original, "longlong"))
902 return (original);
904 dbuf_init (&dbuf, 128);
905 dbuf_printf (&dbuf, "%s_rr%s_%s", original, options.profile ? "f" : "x", options.noRegParams ? "s" : "bds" /* MB: but the library only has hds variants ??? */
908 return dbuf_detach_c_str (&dbuf);
910 #endif
912 static const char *
913 _getRegName (const struct reg_info *reg)
915 if (reg)
917 return reg->name;
919 /* assert (0); */
920 return "err";
923 static int
924 _getRegByName (const char *name)
926 if (!strcmp (name, "a"))
927 return 0;
928 if (!strcmp (name, "c"))
929 return 1;
930 if (!strcmp (name, "b"))
931 return 2;
932 if (!strcmp (name, "e"))
933 return 3;
934 if (!strcmp (name, "d"))
935 return 4;
936 if (!strcmp (name, "l"))
937 return 5;
938 if (!strcmp (name, "h"))
939 return 6;
940 if (!strcmp (name, "iyl"))
941 return 7;
942 if (!strcmp (name, "iyh"))
943 return 8;
944 return -1;
947 static void
948 _z80_genAssemblerStart (FILE * of)
950 if (!options.noOptsdccInAsm)
952 tfprintf (of, "\t!optsdcc -m%s", port->target);
953 fprintf (of, " sdcccall(%d)", options.sdcccall);
954 fprintf (of, "\n");
958 static bool
959 _hasNativeMulFor (iCode *ic, sym_link *left, sym_link *right)
961 sym_link *test = NULL;
962 int result_size = IS_SYMOP (IC_RESULT(ic)) ? getSize (OP_SYM_TYPE (IC_RESULT(ic))) : 4;
964 if (ic->op != '*')
965 return(false);
967 if (IS_BITINT (OP_SYM_TYPE (IC_RESULT(ic))) && SPEC_BITINTWIDTH (OP_SYM_TYPE (IC_RESULT(ic))) % 8)
968 return false;
970 if (IS_LITERAL (left))
971 test = left;
972 else if (IS_LITERAL (right))
973 test = right;
974 /* 8x8 unsigned multiplication code is shorter than
975 call overhead for the multiplication routine. */
976 else if (IS_CHAR (right) && IS_UNSIGNED (right) && IS_CHAR (left) && IS_UNSIGNED (left) && !IS_SM83)
977 return(true);
978 /* Same for any multiplication with 8 bit result. */
979 else if (result_size == 1 && !IS_SM83)
980 return(true);
981 // Rabbits have signed 16x16->32 multiplication, which is broken on original Rabbit 2000.
982 else if (IS_RAB && !IS_R2K && getSize (left) == 2 && getSize(right) == 2 &&
983 (result_size == 2 || result_size <= 4 && !IS_UNSIGNED (left) && !IS_UNSIGNED (right)))
984 return(true);
985 else
986 return(false);
988 if (getSize (test) <= 2)
989 return(true);
991 return(false);
994 /* Indicate which extended bit operations this port supports */
995 static bool
996 hasExtBitOp (int op, sym_link *left, int right)
998 switch (op)
1000 case GETABIT:
1001 case GETBYTE:
1002 case GETWORD:
1003 return (true);
1004 case ROT:
1006 unsigned int lbits = bitsForType (left);
1007 if (lbits % 8)
1008 return (false);
1009 if (lbits == 8)
1010 return (true);
1011 if (right % lbits == 1 || right % lbits == lbits - 1)
1012 return (true);
1013 if ((getSize (left) <= 2 || getSize (left) == 4) && lbits == right * 2)
1014 return (true);
1016 return (false);
1018 return (false);
1021 /* Indicate the expense of an access to an output storage class */
1022 static int
1023 oclsExpense (struct memmap *oclass)
1025 if (IN_FARSPACE (oclass))
1026 return 1;
1028 return 0;
1032 //#define LINKCMD "sdld{port} -nf {dstfilename}"
1034 #define LINKCMD \
1035 "sdld{port} -n -c -- {z80bases} -m -j" \
1036 " {z80libspec}" \
1037 " {z80extralibfiles} {z80extralibpaths}" \
1038 " {z80outputtypeflag} \"{linkdstfilename}\"" \
1039 " {z80crt0}" \
1040 " \"{dstfilename}{objext}\"" \
1041 " {z80extraobj}"
1044 static const char *_z80LinkCmd[] = {
1045 "sdldz80", "-nf", "$1", "$L", NULL
1048 static const char *_gbLinkCmd[] = {
1049 "sdldgb", "-nf", "$1", "$L", NULL
1052 static const char *_gnuLdCmd[] = {
1053 "z80-elf-ld", "", "$1", NULL
1056 /* $3 is replaced by assembler.debug_opts resp. port->assembler.plain_opts */
1057 static const char *_z80AsmCmd[] = {
1058 "sdasz80", "$l", "$3", "$2", "$1.asm", NULL
1061 static const char *_r2kAsmCmd[] = {
1062 "sdasrab", "$l", "$3", "$2", "$1.asm", NULL
1065 static const char *_gbAsmCmd[] = {
1066 "sdasgb", "$l", "$3", "$2", "$1.asm", NULL
1069 static const char *_tlcs90AsmCmd[] = {
1070 "sdastlcs90", "$l", "$3", "$2", "$1.asm", NULL
1073 static const char *_GnuAsmCmd[] = {
1074 "z80-elf-as", "$l", "$3", "$2", "$1.asm", NULL
1077 static const char *const _crt[] = { "crt0.rel", NULL, };
1078 static const char *const _libs_z80[] = { "z80", NULL, };
1079 static const char *const _libs_z180[] = { "z180", NULL, };
1080 static const char *const _libs_r2k[] = { "r2k", NULL, };
1081 static const char *const _libs_r2ka[] = { "r2ka", NULL, };
1082 static const char *const _libs_r3ka[] = { "r3ka", NULL, };
1083 static const char *const _libs_tlcs90[] = { "tlcs90", NULL, };
1084 static const char *const _libs_sm83[] = { "sm83", NULL, };
1085 static const char *const _libs_ez80_z80[] = { "ez80_z80", NULL, };
1086 static const char *const _libs_z80n[] = { "z80n", NULL, };
1087 static const char *const _libs_r800[] = { "r800", NULL, };
1089 /* Globals */
1090 PORT z80_port =
1092 TARGET_ID_Z80,
1093 "z80",
1094 "Zilog Z80", /* Target name */
1095 NULL, /* Processor name */
1097 glue,
1098 FALSE,
1099 NO_MODEL,
1100 NO_MODEL,
1101 NULL, /* model == target */
1103 { /* Assembler */
1104 _z80AsmCmd,
1105 NULL,
1106 "-plosgffwy", /* Options with debug */
1107 "-plosgffw", /* Options without debug */
1109 ".asm"
1111 { /* Linker */
1112 _z80LinkCmd, //NULL,
1113 NULL, //LINKCMD,
1114 NULL,
1115 ".rel",
1116 1, /* needLinkerScript */
1117 _crt, /* crt */
1118 _libs_z80, /* libs */
1120 { /* Peephole optimizer */
1121 _z80_defaultRules,
1122 z80instructionSize,
1126 z80notUsed,
1127 z80canAssign,
1128 z80notUsedFrom,
1129 z80symmParmStack,
1130 z80canJoinRegs,
1131 z80canSplitReg,
1133 /* Sizes: char, short, int, long, long long, near ptr, far ptr, gptr, func ptr, banked func ptr, bit, float, BitInt (in bits) */
1134 { 1, 2, 2, 4, 8, 2, 2, 2, 2, 2, 1, 4, 64 },
1135 /* tags for generic pointers */
1136 { 0x00, 0x40, 0x60, 0x80 }, /* far, near, xstack, code */
1138 "XSEG",
1139 "STACK",
1140 "CODE",
1141 "DATA",
1142 NULL, /* idata */
1143 NULL, /* pdata */
1144 NULL, /* xdata */
1145 NULL, /* bit */
1146 "RSEG (ABS)",
1147 "GSINIT", /* static initialization */
1148 NULL, /* overlay */
1149 "GSFINAL",
1150 "HOME",
1151 NULL, /* xidata */
1152 NULL, /* xinit */
1153 NULL, /* const_name */
1154 "CABS (ABS)", /* cabs_name */
1155 "DABS (ABS)", /* xabs_name */
1156 NULL, /* iabs_name */
1157 "INITIALIZED", /* name of segment for initialized variables */
1158 "INITIALIZER", /* name of segment for copies of initialized variables in code space */
1159 NULL,
1160 NULL,
1161 1, /* CODE is read-only */
1162 false, // unqualified pointers cannot point to __sfr.
1163 1 /* No fancy alignments supported. */
1165 { NULL, NULL },
1166 1, /* ABI revision */
1167 { -1, 0, 0, 4, 0, 3, 0 },
1169 -1, /* shifts never use support routines */
1170 true, /* use support routine for int x int -> long multiplication */
1171 false, /* do not use support routine for unsigned long x unsigned char -> unsigned long long multiplication */
1173 { z80_emitDebuggerSymbol },
1175 256, /* maxCount */
1176 3, /* sizeofElement */
1177 {6, 7, 8}, /* sizeofMatchJump[] - Assumes operand allocated to registers */
1178 {6, 9, 15}, /* sizeofRangeCompare[] - Assumes operand allocated to registers*/
1179 1, /* sizeofSubtract - Assumes use of a singel inc or dec */
1180 9, /* sizeofDispatch - Assumes operand allocated to register e or c*/
1182 "_",
1183 _z80_init,
1184 _parseOptions,
1185 _z80_options,
1186 NULL,
1187 _finaliseOptions,
1188 _setDefaultOptions,
1189 z80_assignRegisters,
1190 _getRegName,
1191 _getRegByName,
1192 NULL,
1193 _keywords,
1194 _z80_genAssemblerStart,
1195 NULL, /* no genAssemblerEnd */
1196 0, /* no local IVT generation code */
1197 0, /* no genXINIT code */
1198 NULL, /* genInitStartup */
1199 _reset_regparm,
1200 _reg_parm,
1201 _process_pragma,
1202 NULL,
1203 _hasNativeMulFor,
1204 hasExtBitOp, /* hasExtBitOp */
1205 oclsExpense, /* oclsExpense */
1206 TRUE,
1207 TRUE, /* little endian */
1208 0, /* leave lt */
1209 0, /* leave gt */
1210 1, /* transform <= to ! > */
1211 1, /* transform >= to ! < */
1212 1, /* transform != to !(a == b) */
1213 0, /* leave == */
1214 FALSE, /* Array initializer support. */
1215 0, /* no CSE cost estimation yet */
1216 _z80_builtins, /* builtin functions */
1217 GPOINTER, /* treat unqualified pointers as "generic" pointers */
1218 1, /* reset labelKey to 1 */
1219 1, /* globals & local statics allowed */
1220 9, /* Number of registers handled in the tree-decomposition-based register allocator in SDCCralloc.hpp */
1221 PORT_MAGIC
1224 PORT z180_port =
1226 TARGET_ID_Z180,
1227 "z180",
1228 "Zilog Z180", /* Target name */
1229 NULL, /* Processor name */
1231 glue,
1232 FALSE,
1233 NO_MODEL,
1234 NO_MODEL,
1235 NULL, /* model == target */
1237 { /* Assembler */
1238 _z80AsmCmd,
1239 NULL,
1240 "-plosgffwy", /* Options with debug */
1241 "-plosgffw", /* Options without debug */
1243 ".asm"
1245 { /* Linker */
1246 _z80LinkCmd, //NULL,
1247 NULL, //LINKCMD,
1248 NULL,
1249 ".rel",
1251 _crt, /* crt */
1252 _libs_z180, /* libs */
1254 { /* Peephole optimizer */
1255 _z80_defaultRules,
1256 z80instructionSize,
1257 NULL,
1258 NULL,
1259 NULL,
1260 z80notUsed,
1261 z80canAssign,
1262 z80notUsedFrom,
1263 z80symmParmStack,
1264 z80canJoinRegs,
1265 z80canSplitReg,
1267 /* Sizes: char, short, int, long, long long, near ptr, far ptr, gptr, func ptr, banked func ptr, bit, float, BitInt (in bits) */
1268 { 1, 2, 2, 4, 8, 2, 2, 2, 2, 2, 1, 4, 64 },
1269 /* tags for generic pointers */
1270 { 0x00, 0x40, 0x60, 0x80 }, /* far, near, xstack, code */
1272 "XSEG",
1273 "STACK",
1274 "CODE",
1275 "DATA",
1276 NULL, /* idata */
1277 NULL, /* pdata */
1278 NULL, /* xdata */
1279 NULL, /* bit */
1280 "RSEG (ABS)",
1281 "GSINIT",
1282 NULL, /* overlay */
1283 "GSFINAL",
1284 "HOME",
1285 NULL, /* xidata */
1286 NULL, /* xinit */
1287 NULL, /* const_name */
1288 "CABS (ABS)", /* cabs_name */
1289 "DABS (ABS)", /* xabs_name */
1290 NULL, /* iabs_name */
1291 "INITIALIZED", /* name of segment for initialized variables */
1292 "INITIALIZER", /* name of segment for copies of initialized variables in code space */
1293 NULL,
1294 NULL,
1295 1, /* CODE is read-only */
1296 false, // unqualified pointers cannot point to __sfr.
1297 1 /* No fancy alignments supported. */
1299 { NULL, NULL },
1300 1, /* ABI revision */
1301 { -1, 0, 0, 4, 0, 3, 0 },
1303 -1, /* shifts never use support routines */
1304 false, /* do not use support routine for int x int -> long multiplication */
1305 false, /* do not use support routine for unsigned long x unsigned char -> unsigned long long multiplication */
1307 { z80_emitDebuggerSymbol },
1309 8000, /* maxCount */
1310 2, /* sizeofElement */
1311 {6, 7, 8}, /* sizeofMatchJump[] - Assumes operand allocated to registers */
1312 {6, 9, 15}, /* sizeofRangeCompare[] - Assumes operand allocated to registers*/
1313 1, /* sizeofSubtract - Assumes use of a single inc or dec */
1314 9, /* sizeofDispatch - Assumes operand allocated to register e or c*/
1316 "_",
1317 _z180_init,
1318 _parseOptions,
1319 _z80_like_options,
1320 NULL,
1321 _finaliseOptions,
1322 _setDefaultOptions,
1323 z80_assignRegisters,
1324 _getRegName,
1325 _getRegByName,
1326 NULL,
1327 _keywords,
1328 _z80_genAssemblerStart,
1329 NULL, /* no genAssemblerEnd */
1330 0, /* no local IVT generation code */
1331 0, /* no genXINIT code */
1332 NULL, /* genInitStartup */
1333 _reset_regparm,
1334 _reg_parm,
1335 _process_pragma,
1336 NULL,
1337 _hasNativeMulFor,
1338 hasExtBitOp, /* hasExtBitOp */
1339 oclsExpense, /* oclsExpense */
1340 TRUE,
1341 TRUE, /* little endian */
1342 0, /* leave lt */
1343 0, /* leave gt */
1344 1, /* transform <= to ! > */
1345 1, /* transform >= to ! < */
1346 1, /* transform != to !(a == b) */
1347 0, /* leave == */
1348 FALSE, /* Array initializer support. */
1349 0, /* no CSE cost estimation yet */
1350 _z80_builtins, /* builtin functions */
1351 GPOINTER, /* treat unqualified pointers as "generic" pointers */
1352 1, /* reset labelKey to 1 */
1353 1, /* globals & local statics allowed */
1354 9, /* Number of registers handled in the tree-decomposition-based register allocator in SDCCralloc.hpp */
1355 PORT_MAGIC
1358 PORT r2k_port =
1360 TARGET_ID_R2K,
1361 "r2k",
1362 "Rabbit 2000", /* Target name */
1363 NULL, /* Processor name */
1365 glue,
1366 FALSE,
1367 NO_MODEL,
1368 NO_MODEL,
1369 NULL, /* model == target */
1371 { /* Assembler */
1372 _r2kAsmCmd,
1373 NULL,
1374 "-plosgffwy", /* Options with debug */
1375 "-plosgffw", /* Options without debug */
1377 ".asm"},
1378 { /* Linker */
1379 _z80LinkCmd, //NULL,
1380 NULL, //LINKCMD,
1381 NULL,
1382 ".rel",
1384 _crt, /* crt */
1385 _libs_r2k, /* libs */
1387 { /* Peephole optimizer */
1388 _r2k_defaultRules,
1389 z80instructionSize,
1390 NULL,
1391 NULL,
1392 NULL,
1393 z80notUsed,
1394 z80canAssign,
1395 z80notUsedFrom,
1396 z80symmParmStack,
1397 z80canJoinRegs,
1398 z80canSplitReg,
1400 /* Sizes: char, short, int, long, long long, near ptr, far ptr, gptr, func ptr, banked func ptr, bit, float, _BitInt (in bits) */
1401 { 1, 2, 2, 4, 8, 2, 2, 2, 2, 2, 1, 4, 64 },
1402 /* tags for generic pointers */
1403 { 0x00, 0x40, 0x60, 0x80 }, /* far, near, xstack, code */
1405 "XSEG",
1406 "STACK",
1407 "CODE",
1408 "DATA",
1409 NULL, /* idata */
1410 NULL, /* pdata */
1411 NULL, /* xdata */
1412 NULL, /* bit */
1413 "RSEG (ABS)",
1414 "GSINIT",
1415 NULL, /* overlay */
1416 "GSFINAL",
1417 "HOME",
1418 NULL, /* xidata */
1419 NULL, /* xinit */
1420 NULL, /* const_name */
1421 "CABS (ABS)", /* cabs_name */
1422 "DABS (ABS)", /* xabs_name */
1423 NULL, /* iabs_name */
1424 "INITIALIZED", /* name of segment for initialized variables */
1425 "INITIALIZER", /* name of segment for copies of initialized variables in code space */
1426 NULL,
1427 NULL,
1428 1, /* CODE is read-only */
1429 false, // unqualified pointers cannot point to __sfr.
1430 1 /* No fancy alignments supported. */
1432 { NULL, NULL },
1433 1, /* ABI revision */
1434 { -1, 0, 0, 4, 0, 2, 0 },
1436 -1, /* shifts never use support routines */
1437 false, /* do not use support routine for int x int -> long multiplication */
1438 false, /* do not use support routine for unsigned long x unsigned char -> unsigned long long multiplication */
1440 { z80_emitDebuggerSymbol },
1442 8000, /* maxCount */
1443 2, /* sizeofElement */
1444 {6, 7, 8}, /* sizeofMatchJump[] - Assumes operand allocated to registers */
1445 {6, 9, 15}, /* sizeofRangeCompare[] - Assumes operand allocated to registers*/
1446 1, /* sizeofSubtract - Assumes use of a single inc or dec */
1447 8, /* sizeofDispatch - Assumes operand allocated to register e or c*/
1449 "_",
1450 _r2k_init,
1451 _parseOptions,
1452 _z80_like_options,
1453 NULL,
1454 _finaliseOptions,
1455 _setDefaultOptions,
1456 z80_assignRegisters,
1457 _getRegName,
1458 _getRegByName,
1459 NULL,
1460 _keywords,
1461 _z80_genAssemblerStart,
1462 NULL, /* no genAssemblerEnd */
1463 0, /* no local IVT generation code */
1464 0, /* no genXINIT code */
1465 NULL, /* genInitStartup */
1466 _reset_regparm,
1467 _reg_parm,
1468 _process_pragma,
1469 NULL,
1470 _hasNativeMulFor,
1471 hasExtBitOp, /* hasExtBitOp */
1472 oclsExpense, /* oclsExpense */
1473 TRUE,
1474 TRUE, /* little endian */
1475 0, /* leave lt */
1476 0, /* leave gt */
1477 1, /* transform <= to ! > */
1478 1, /* transform >= to ! < */
1479 1, /* transform != to !(a == b) */
1480 0, /* leave == */
1481 FALSE, /* Array initializer support. */
1482 0, /* no CSE cost estimation yet */
1483 _z80_builtins, /* builtin functions */
1484 GPOINTER, /* treat unqualified pointers as "generic" pointers */
1485 1, /* reset labelKey to 1 */
1486 1, /* globals & local statics allowed */
1487 9, /* Number of registers handled in the tree-decomposition-based register allocator in SDCCralloc.hpp */
1488 PORT_MAGIC
1491 PORT r2ka_port =
1493 TARGET_ID_R2KA,
1494 "r2ka",
1495 "Rabbit 2000A", /* Target name */
1496 NULL, /* Processor name */
1498 glue,
1499 FALSE,
1500 NO_MODEL,
1501 NO_MODEL,
1502 NULL, /* model == target */
1504 { /* Assembler */
1505 _r2kAsmCmd,
1506 NULL,
1507 "-plosgffwy", /* Options with debug */
1508 "-plosgffw", /* Options without debug */
1510 ".asm"
1512 { /* Linker */
1513 _z80LinkCmd, //NULL,
1514 NULL, //LINKCMD,
1515 NULL,
1516 ".rel",
1518 _crt, /* crt */
1519 _libs_r2ka, /* libs */
1521 { /* Peephole optimizer */
1522 _r2k_defaultRules,
1523 z80instructionSize,
1527 z80notUsed,
1528 z80canAssign,
1529 z80notUsedFrom,
1530 z80symmParmStack,
1531 z80canJoinRegs,
1532 z80canSplitReg,
1534 /* Sizes: char, short, int, long, long long, near ptr, far ptr, gptr, func ptr, banked func ptr, bit, float, BitInt (in bits) */
1535 { 1, 2, 2, 4, 8, 2, 2, 2, 2, 2, 1, 4, 64 },
1536 /* tags for generic pointers */
1537 { 0x00, 0x40, 0x60, 0x80 }, /* far, near, xstack, code */
1539 "XSEG",
1540 "STACK",
1541 "CODE",
1542 "DATA",
1543 NULL, /* idata */
1544 NULL, /* pdata */
1545 NULL, /* xdata */
1546 NULL, /* bit */
1547 "RSEG (ABS)",
1548 "GSINIT",
1549 NULL, /* overlay */
1550 "GSFINAL",
1551 "HOME",
1552 NULL, /* xidata */
1553 NULL, /* xinit */
1554 NULL, /* const_name */
1555 "CABS (ABS)", /* cabs_name */
1556 "DABS (ABS)", /* xabs_name */
1557 NULL, /* iabs_name */
1558 "INITIALIZED", /* name of segment for initialized variables */
1559 "INITIALIZER", /* name of segment for copies of initialized variables in code space */
1560 NULL,
1561 NULL,
1562 1, /* CODE is read-only */
1563 false, // unqualified pointers cannot point to __sfr.
1564 1 /* No fancy alignments supported. */
1566 { NULL, NULL },
1567 1, /* ABI revision */
1568 { -1, 0, 0, 4, 0, 2, 0 },
1570 -1, /* shifts never use support routines */
1571 false, /* do not use support routine for int x int -> long multiplication */
1572 false, /* do not use support routine for unsigned long x unsigned char -> unsigned long long multiplication */
1574 { z80_emitDebuggerSymbol },
1576 8000, /* maxCount */
1577 2, /* sizeofElement */
1578 {6, 7, 8}, /* sizeofMatchJump[] - Assumes operand allocated to registers */
1579 {6, 9, 15}, /* sizeofRangeCompare[] - Assumes operand allocated to registers*/
1580 1, /* sizeofSubtract - Assumes use of a single inc or dec */
1581 8, /* sizeofDispatch - Assumes operand allocated to register e or c*/
1583 "_",
1584 _r2ka_init,
1585 _parseOptions,
1586 _z80_like_options,
1587 NULL,
1588 _finaliseOptions,
1589 _setDefaultOptions,
1590 z80_assignRegisters,
1591 _getRegName,
1592 _getRegByName,
1593 NULL,
1594 _keywords,
1595 _z80_genAssemblerStart,
1596 NULL, /* no genAssemblerEnd */
1597 0, /* no local IVT generation code */
1598 0, /* no genXINIT code */
1599 NULL, /* genInitStartup */
1600 _reset_regparm,
1601 _reg_parm,
1602 _process_pragma,
1603 NULL,
1604 _hasNativeMulFor,
1605 hasExtBitOp, /* hasExtBitOp */
1606 oclsExpense, /* oclsExpense */
1607 TRUE,
1608 TRUE, /* little endian */
1609 0, /* leave lt */
1610 0, /* leave gt */
1611 1, /* transform <= to ! > */
1612 1, /* transform >= to ! < */
1613 1, /* transform != to !(a == b) */
1614 0, /* leave == */
1615 FALSE, /* Array initializer support. */
1616 0, /* no CSE cost estimation yet */
1617 _z80_builtins, /* builtin functions */
1618 GPOINTER, /* treat unqualified pointers as "generic" pointers */
1619 1, /* reset labelKey to 1 */
1620 1, /* globals & local statics allowed */
1621 9, /* Number of registers handled in the tree-decomposition-based register allocator in SDCCralloc.hpp */
1622 PORT_MAGIC
1625 PORT r3ka_port =
1627 TARGET_ID_R3KA,
1628 "r3ka",
1629 "Rabbit 3000A", /* Target name */
1630 NULL, /* Processor name */
1632 glue,
1633 FALSE,
1634 NO_MODEL,
1635 NO_MODEL,
1636 NULL, /* model == target */
1638 { /* Assembler */
1639 _r2kAsmCmd,
1640 NULL,
1641 "-plosgffwy", /* Options with debug */
1642 "-plosgffw", /* Options without debug */
1644 ".asm"
1646 { /* Linker */
1647 _z80LinkCmd, //NULL,
1648 NULL, //LINKCMD,
1649 NULL,
1650 ".rel",
1652 _crt, /* crt */
1653 _libs_r3ka, /* libs */
1655 { /* Peephole optimizer */
1656 _r2k_defaultRules,
1657 z80instructionSize,
1661 z80notUsed,
1662 z80canAssign,
1663 z80notUsedFrom,
1664 z80symmParmStack,
1665 z80canJoinRegs,
1666 z80canSplitReg,
1668 /* Sizes: char, short, int, long, long long, near ptr, far ptr, gptr, func ptr, banked func ptr, bit, float, BitInt (in bits) */
1669 { 1, 2, 2, 4, 8, 2, 2, 2, 2, 2, 1, 4, 64 },
1670 /* tags for generic pointers */
1671 { 0x00, 0x40, 0x60, 0x80 }, /* far, near, xstack, code */
1673 "XSEG",
1674 "STACK",
1675 "CODE",
1676 "DATA",
1677 NULL, /* idata */
1678 NULL, /* pdata */
1679 NULL, /* xdata */
1680 NULL, /* bit */
1681 "RSEG (ABS)",
1682 "GSINIT",
1683 NULL, /* overlay */
1684 "GSFINAL",
1685 "HOME",
1686 NULL, /* xidata */
1687 NULL, /* xinit */
1688 NULL, /* const_name */
1689 "CABS (ABS)", /* cabs_name */
1690 "DABS (ABS)", /* xabs_name */
1691 NULL, /* iabs_name */
1692 "INITIALIZED", /* name of segment for initialized variables */
1693 "INITIALIZER", /* name of segment for copies of initialized variables in code space */
1694 NULL,
1695 NULL,
1696 1, /* CODE is read-only */
1697 false, // unqualified pointers cannot point to __sfr.
1698 1 /* No fancy alignments supported. */
1700 { NULL, NULL },
1701 1, /* ABI revision */
1702 { -1, 0, 0, 4, 0, 2, 0 },
1704 -1, /* shifts never use support routines */
1705 false, /* do not use support routine for int x int -> long multiplication */
1706 false, /* do not use support routine for unsigned long x unsigned char -> unsigned long long multiplication */
1708 { z80_emitDebuggerSymbol },
1710 8000, /* maxCount */
1711 2, /* sizeofElement */
1712 {6, 7, 8}, /* sizeofMatchJump[] - Assumes operand allocated to registers */
1713 {6, 9, 15}, /* sizeofRangeCompare[] - Assumes operand allocated to registers*/
1714 1, /* sizeofSubtract - Assumes use of a single inc or dec */
1715 8, /* sizeofDispatch - Assumes operand allocated to register e or c*/
1717 "_",
1718 _r3ka_init,
1719 _parseOptions,
1720 _z80_like_options,
1721 NULL,
1722 _finaliseOptions,
1723 _setDefaultOptions,
1724 z80_assignRegisters,
1725 _getRegName,
1726 _getRegByName,
1727 NULL,
1728 _keywords,
1729 _z80_genAssemblerStart,
1730 NULL, /* no genAssemblerEnd */
1731 0, /* no local IVT generation code */
1732 0, /* no genXINIT code */
1733 NULL, /* genInitStartup */
1734 _reset_regparm,
1735 _reg_parm,
1736 _process_pragma,
1737 NULL,
1738 _hasNativeMulFor,
1739 hasExtBitOp, /* hasExtBitOp */
1740 oclsExpense, /* oclsExpense */
1741 TRUE,
1742 TRUE, /* little endian */
1743 0, /* leave lt */
1744 0, /* leave gt */
1745 1, /* transform <= to ! > */
1746 1, /* transform >= to ! < */
1747 1, /* transform != to !(a == b) */
1748 0, /* leave == */
1749 FALSE, /* Array initializer support. */
1750 0, /* no CSE cost estimation yet */
1751 _z80_builtins, /* builtin functions */
1752 GPOINTER, /* treat unqualified pointers as "generic" pointers */
1753 1, /* reset labelKey to 1 */
1754 1, /* globals & local statics allowed */
1755 9, /* Number of registers handled in the tree-decomposition-based register allocator in SDCCralloc.hpp */
1756 PORT_MAGIC
1759 /* Globals */
1760 PORT sm83_port =
1762 TARGET_ID_SM83,
1763 "sm83",
1764 "Sharp SM83", /* Target name */
1765 NULL,
1767 glue,
1768 FALSE,
1769 NO_MODEL,
1770 NO_MODEL,
1771 NULL, /* model == target */
1773 { /* Assembler */
1774 _gbAsmCmd,
1775 NULL,
1776 "-plosgffwy", /* Options with debug */
1777 "-plosgffw", /* Options without debug */
1779 ".asm",
1780 NULL /* no do_assemble function */
1782 { /* Linker */
1783 _gbLinkCmd, //NULL,
1784 NULL, //LINKCMD,
1785 NULL,
1786 ".rel",
1788 _crt, /* crt */
1789 _libs_sm83, /* libs */
1791 { /* Peephole optimizer */
1792 _sm83_defaultRules,
1793 z80instructionSize,
1794 NULL,
1795 NULL,
1796 NULL,
1797 z80notUsed,
1798 z80canAssign,
1799 z80notUsedFrom,
1800 z80symmParmStack,
1801 z80canJoinRegs,
1802 z80canSplitReg,
1804 /* Sizes: char, short, int, long, long long, near ptr, far ptr, gptr, func ptr, banked func ptr, bit, float, BitInt (in bits) */
1805 { 1, 2, 2, 4, 8, 2, 2, 2, 2, 2, 1, 4, 64 /* non-compliant - C23 rewuires t least 64 here. SM83 has some special paths in codegen for + and - of more than 16 bits. Those do not yet support _BitInt */ },
1806 /* tags for generic pointers */
1807 { 0x00, 0x40, 0x60, 0x80 }, /* far, near, xstack, code */
1809 "XSEG",
1810 "STACK",
1811 "CODE",
1812 "DATA",
1813 NULL, /* idata */
1814 NULL, /* pdata */
1815 NULL, /* xdata */
1816 NULL, /* bit */
1817 "RSEG",
1818 "GSINIT",
1819 NULL, /* overlay */
1820 "GSFINAL",
1821 "HOME",
1822 NULL, /* xidata */
1823 NULL, /* xinit */
1824 NULL, /* const_name */
1825 "CABS (ABS)", /* cabs_name */
1826 "DABS (ABS)", /* xabs_name */
1827 NULL, /* iabs_name */
1828 "INITIALIZED", /* name of segment for initialized variables */
1829 "INITIALIZER", /* name of segment for copies of initialized variables in code space */
1830 NULL,
1831 NULL,
1832 1, /* CODE is read-only */
1833 true, // unqualified pointers can point to __sfr (the i/o space is part of the flat address space).
1834 1 /* No fancy alignments supported. */
1836 { NULL, NULL },
1837 1, /* default ABI revision */
1838 { -1, 0, 0, 2, 0, 4, 0 },
1840 -1, /* shifts never use support routines */
1841 false, /* do not use support routine for int x int -> long multiplication */
1842 false, /* do not use support routine for unsigned long x unsigned char -> unsigned long long multiplication */
1844 { z80_emitDebuggerSymbol },
1846 8000, /* maxCount */
1847 2, /* sizeofElement */
1848 {6, 7, 8}, /* sizeofMatchJump[] - Assumes operand allocated to registers */
1849 {6, 9, 15}, /* sizeofRangeCompare[] - Assumes operand allocated to registers*/
1850 1, /* sizeofSubtract - Assumes use of a single inc or dec */
1851 9, /* sizeofDispatch - Assumes operand allocated to register e or c*/
1853 "_",
1854 _sm83_init,
1855 _parseOptions,
1856 _sm83_options,
1857 NULL,
1858 _finaliseOptions,
1859 _setDefaultOptions,
1860 z80_assignRegisters,
1861 _getRegName,
1862 _getRegByName,
1863 NULL,
1864 _keywordsgb,
1865 _z80_genAssemblerStart,
1866 NULL, /* no genAssemblerEnd */
1867 0, /* no local IVT generation code */
1868 0, /* no genXINIT code */
1869 NULL, /* genInitStartup */
1870 _reset_regparm,
1871 _reg_parm,
1872 _process_pragma,
1873 NULL,
1874 _hasNativeMulFor,
1875 hasExtBitOp, /* hasExtBitOp */
1876 oclsExpense, /* oclsExpense */
1877 TRUE,
1878 TRUE, /* little endian */
1879 0, /* leave lt */
1880 0, /* leave gt */
1881 1, /* transform <= to ! > */
1882 1, /* transform >= to ! < */
1883 1, /* transform != to !(a == b) */
1884 0, /* leave == */
1885 false, /* Array initializer support. */
1886 0, /* no CSE cost estimation yet */
1887 NULL, /* no builtin functions */
1888 GPOINTER, /* treat unqualified pointers as "generic" pointers */
1889 1, /* reset labelKey to 1 */
1890 1, /* globals & local statics allowed */
1891 7, /* Number of registers handled in the tree-decomposition-based register allocator in SDCCralloc.hpp */
1892 PORT_MAGIC
1895 PORT tlcs90_port =
1897 TARGET_ID_TLCS90,
1898 "tlcs90",
1899 "Toshiba TLCS-90", /* Target name */
1900 NULL, /* Processor name */
1902 glue,
1903 FALSE,
1904 NO_MODEL,
1905 NO_MODEL,
1906 NULL, /* model == target */
1908 { /* Assembler */
1909 _tlcs90AsmCmd,
1910 NULL,
1911 "-plosgffwy", /* Options with debug */
1912 "-plosgffw", /* Options without debug */
1914 ".asm"
1916 { /* Linker */
1917 _z80LinkCmd, //NULL,
1918 NULL, //LINKCMD,
1919 NULL,
1920 ".rel",
1922 _crt, /* crt */
1923 _libs_tlcs90, /* libs */
1925 { /* Peephole optimizer */
1926 _tlcs90_defaultRules,
1927 z80instructionSize,
1928 NULL,
1929 NULL,
1930 NULL,
1931 z80notUsed,
1932 z80canAssign,
1933 z80notUsedFrom,
1934 z80symmParmStack,
1935 z80canJoinRegs,
1936 z80canSplitReg,
1938 /* Sizes: char, short, int, long, long long, near ptr, far ptr, gptr, func ptr, banked func ptr, bit, float, BitInt (in bits) */
1939 { 1, 2, 2, 4, 8, 2, 2, 2, 2, 2, 1, 4, 64 },
1940 /* tags for generic pointers */
1941 { 0x00, 0x40, 0x60, 0x80 }, /* far, near, xstack, code */
1943 "XSEG",
1944 "STACK",
1945 "CODE",
1946 "DATA",
1947 NULL, /* idata */
1948 NULL, /* pdata */
1949 NULL, /* xdata */
1950 NULL, /* bit */
1951 "RSEG (ABS)",
1952 "GSINIT", /* static initialization */
1953 NULL, /* overlay */
1954 "GSFINAL",
1955 "HOME",
1956 NULL, /* xidata */
1957 NULL, /* xinit */
1958 NULL, /* const_name */
1959 "CABS (ABS)", /* cabs_name */
1960 "DABS (ABS)", /* xabs_name */
1961 NULL, /* iabs_name */
1962 "INITIALIZED", /* name of segment for initialized variables */
1963 "INITIALIZER", /* name of segment for copies of initialized variables in code space */
1964 NULL,
1965 NULL,
1966 1, /* CODE is read-only */
1967 false, // doesn't matter, as port has no __sfr anyway
1968 1 /* No fancy alignments supported. */
1970 { NULL, NULL },
1971 1, /* ABI revision */
1972 { -1, 0, 0, 4, 0, 2, 0 },
1974 -1, /* shifts never use support routines */
1975 false, /* do not use support routine for int x int -> long multiplication */
1976 false, /* do not use support routine for unsigned long x unsigned char -> unsigned long long multiplication */
1978 { z80_emitDebuggerSymbol },
1980 8000, /* maxCount */
1981 2, /* sizeofElement */
1982 {6, 7, 8}, /* sizeofMatchJump[] - Assumes operand allocated to registers */
1983 {6, 9, 15}, /* sizeofRangeCompare[] - Assumes operand allocated to registers*/
1984 1, /* sizeofSubtract - Assumes use of a single inc or dec */
1985 9, /* sizeofDispatch - Assumes operand allocated to register e or c*/
1987 "_",
1988 _tlcs90_init,
1989 _parseOptions,
1990 _z80_like_options,
1991 NULL,
1992 _finaliseOptions,
1993 _setDefaultOptions,
1994 z80_assignRegisters,
1995 _getRegName,
1996 _getRegByName,
1997 NULL,
1998 _keywordstlcs90,
1999 _z80_genAssemblerStart,
2000 NULL, /* no genAssemblerEnd */
2001 0, /* no local IVT generation code */
2002 0, /* no genXINIT code */
2003 NULL, /* genInitStartup */
2004 _reset_regparm,
2005 _reg_parm,
2006 _process_pragma,
2007 NULL,
2008 _hasNativeMulFor,
2009 hasExtBitOp, /* hasExtBitOp */
2010 oclsExpense, /* oclsExpense */
2011 TRUE,
2012 TRUE, /* little endian */
2013 0, /* leave lt */
2014 0, /* leave gt */
2015 1, /* transform <= to ! > */
2016 1, /* transform >= to ! < */
2017 1, /* transform != to !(a == b) */
2018 0, /* leave == */
2019 FALSE, /* Array initializer support. */
2020 0, /* no CSE cost estimation yet */
2021 0, /* no builtin functions */
2022 GPOINTER, /* treat unqualified pointers as "generic" pointers */
2023 1, /* reset labelKey to 1 */
2024 1, /* globals & local statics allowed */
2025 9, /* Number of registers handled in the tree-decomposition-based register allocator in SDCCralloc.hpp */
2026 PORT_MAGIC
2029 PORT ez80_z80_port =
2031 TARGET_ID_EZ80_Z80,
2032 "ez80_z80",
2033 "eZ80-Z80", /* Target name */
2034 NULL, /* Processor name */
2036 glue,
2037 FALSE,
2038 NO_MODEL,
2039 NO_MODEL,
2040 NULL, /* model == target */
2042 { /* Assembler */
2043 _z80AsmCmd,
2044 NULL,
2045 "-plosgffwy", /* Options with debug */
2046 "-plosgffw", /* Options without debug */
2048 ".asm"
2050 { /* Linker */
2051 _z80LinkCmd, //NULL,
2052 NULL, //LINKCMD,
2053 NULL,
2054 ".rel",
2056 _crt, /* crt */
2057 _libs_ez80_z80, /* libs */
2059 { /* Peephole optimizer */
2060 _ez80_z80_defaultRules,
2061 z80instructionSize,
2062 NULL,
2063 NULL,
2064 NULL,
2065 z80notUsed,
2066 z80canAssign,
2067 z80notUsedFrom,
2068 z80symmParmStack,
2069 z80canJoinRegs,
2070 z80canSplitReg,
2072 /* Sizes: char, short, int, long, long long, near ptr, far ptr, gptr, func ptr, banked func ptr, bit, float, BitInt (in bits) */
2073 { 1, 2, 2, 4, 8, 2, 2, 2, 2, 2, 1, 4, 64 },
2074 /* tags for generic pointers */
2075 { 0x00, 0x40, 0x60, 0x80 }, /* far, near, xstack, code */
2077 "XSEG",
2078 "STACK",
2079 "CODE",
2080 "DATA",
2081 NULL, /* idata */
2082 NULL, /* pdata */
2083 NULL, /* xdata */
2084 NULL, /* bit */
2085 "RSEG (ABS)",
2086 "GSINIT",
2087 NULL, /* overlay */
2088 "GSFINAL",
2089 "HOME",
2090 NULL, /* xidata */
2091 NULL, /* xinit */
2092 NULL, /* const_name */
2093 "CABS (ABS)", /* cabs_name */
2094 "DABS (ABS)", /* xabs_name */
2095 NULL, /* iabs_name */
2096 "INITIALIZED", /* name of segment for initialized variables */
2097 "INITIALIZER", /* name of segment for copies of initialized variables in code space */
2098 NULL,
2099 NULL,
2100 1, /* CODE is read-only */
2101 false, // unqualified pointers cannot point to __sfr.
2102 1 /* No fancy alignments supported. */
2104 { NULL, NULL },
2105 1, /* ABI revision */
2106 { -1, 0, 0, 4, 0, 3, 0 },
2108 -1, /* shifts never use support routines */
2109 false, /* do not use support routine for int x int -> long multiplication */
2110 false, /* do not use support routine for unsigned long x unsigned char -> unsigned long long multiplication */
2112 { z80_emitDebuggerSymbol },
2114 8000, /* maxCount */
2115 2, /* sizeofElement */
2116 {6, 7, 8}, /* sizeofMatchJump[] - Assumes operand allocated to registers */
2117 {6, 9, 15}, /* sizeofRangeCompare[] - Assumes operand allocated to registers*/
2118 1, /* sizeofSubtract - Assumes use of a single inc or dec */
2119 7, /* sizeofDispatch - Assumes operand allocated to register e or c*/
2121 "_",
2122 _ez80_z80_init,
2123 _parseOptions,
2124 _z80_like_options,
2125 NULL,
2126 _finaliseOptions,
2127 _setDefaultOptions,
2128 z80_assignRegisters,
2129 _getRegName,
2130 _getRegByName,
2131 NULL,
2132 _keywords,
2133 _z80_genAssemblerStart,
2134 NULL, /* no genAssemblerEnd */
2135 0, /* no local IVT generation code */
2136 0, /* no genXINIT code */
2137 NULL, /* genInitStartup */
2138 _reset_regparm,
2139 _reg_parm,
2140 _process_pragma,
2141 NULL,
2142 _hasNativeMulFor,
2143 hasExtBitOp, /* hasExtBitOp */
2144 oclsExpense, /* oclsExpense */
2145 TRUE,
2146 TRUE, /* little endian */
2147 0, /* leave lt */
2148 0, /* leave gt */
2149 1, /* transform <= to ! > */
2150 1, /* transform >= to ! < */
2151 1, /* transform != to !(a == b) */
2152 0, /* leave == */
2153 FALSE, /* Array initializer support. */
2154 0, /* no CSE cost estimation yet */
2155 _z80_builtins, /* builtin functions */
2156 GPOINTER, /* treat unqualified pointers as "generic" pointers */
2157 1, /* reset labelKey to 1 */
2158 1, /* globals & local statics allowed */
2159 9, /* Number of registers handled in the tree-decomposition-based register allocator in SDCCralloc.hpp */
2160 PORT_MAGIC
2163 PORT z80n_port =
2165 TARGET_ID_Z80N,
2166 "z80n",
2167 "Z80N", /* Target name */
2168 NULL, /* Processor name */
2170 glue,
2171 FALSE,
2172 NO_MODEL,
2173 NO_MODEL,
2174 NULL, /* model == target */
2176 { /* Assembler */
2177 _z80AsmCmd,
2178 NULL,
2179 "-plosgffwy", /* Options with debug */
2180 "-plosgffw", /* Options without debug */
2182 ".asm"
2184 { /* Linker */
2185 _z80LinkCmd, //NULL,
2186 NULL, //LINKCMD,
2187 NULL,
2188 ".rel",
2190 _crt, /* crt */
2191 _libs_z80n, /* libs */
2193 { /* Peephole optimizer */
2194 _z80n_defaultRules,
2195 z80instructionSize,
2196 NULL,
2197 NULL,
2198 NULL,
2199 z80notUsed,
2200 z80canAssign,
2201 z80notUsedFrom,
2202 z80symmParmStack,
2203 z80canJoinRegs,
2204 z80canSplitReg,
2206 /* Sizes: char, short, int, long, long long, near ptr, far ptr, gptr, func ptr, banked func ptr, bit, float, BitInt (in bits) */
2207 { 1, 2, 2, 4, 8, 2, 2, 2, 2, 2, 1, 4, 64 },
2208 /* tags for generic pointers */
2209 { 0x00, 0x40, 0x60, 0x80 }, /* far, near, xstack, code */
2211 "XSEG",
2212 "STACK",
2213 "CODE",
2214 "DATA",
2215 NULL, /* idata */
2216 NULL, /* pdata */
2217 NULL, /* xdata */
2218 NULL, /* bit */
2219 "RSEG (ABS)",
2220 "GSINIT",
2221 NULL, /* overlay */
2222 "GSFINAL",
2223 "HOME",
2224 NULL, /* xidata */
2225 NULL, /* xinit */
2226 NULL, /* const_name */
2227 "CABS (ABS)", /* cabs_name */
2228 "DABS (ABS)", /* xabs_name */
2229 NULL, /* iabs_name */
2230 "INITIALIZED", /* name of segment for initialized variables */
2231 "INITIALIZER", /* name of segment for copies of initialized variables in code space */
2232 NULL,
2233 NULL,
2234 1, /* CODE is read-only */
2235 false, // unqualified pointers cannot point to __sfr.
2236 1 /* No fancy alignments supported. */
2238 { NULL, NULL },
2239 1, /* ABI revision */
2240 { -1, 0, 0, 4, 0, 3, 0 },
2242 -1, /* shifts never use support routines */
2243 false, /* do not use support routine for int x int -> long multiplication */
2244 false, /* do not use support routine for unsigned long x unsigned char -> unsigned long long multiplication */
2246 { z80_emitDebuggerSymbol },
2248 8000, /* maxCount */
2249 2, /* sizeofElement */
2250 {6, 7, 8}, /* sizeofMatchJump[] - Assumes operand allocated to registers */
2251 {6, 9, 15}, /* sizeofRangeCompare[] - Assumes operand allocated to registers*/
2252 1, /* sizeofSubtract - Assumes use of a single inc or dec */
2253 9, /* sizeofDispatch - Assumes operand allocated to register e or c*/
2255 "_",
2256 _z80n_init,
2257 _parseOptions,
2258 _z80_like_options,
2259 NULL,
2260 _finaliseOptions,
2261 _setDefaultOptions,
2262 z80_assignRegisters,
2263 _getRegName,
2264 _getRegByName,
2265 NULL,
2266 _keywords,
2267 _z80_genAssemblerStart,
2268 NULL, /* no genAssemblerEnd */
2269 0, /* no local IVT generation code */
2270 0, /* no genXINIT code */
2271 NULL, /* genInitStartup */
2272 _reset_regparm,
2273 _reg_parm,
2274 _process_pragma,
2275 NULL,
2276 _hasNativeMulFor,
2277 hasExtBitOp, /* hasExtBitOp */
2278 oclsExpense, /* oclsExpense */
2279 TRUE,
2280 TRUE, /* little endian */
2281 0, /* leave lt */
2282 0, /* leave gt */
2283 1, /* transform <= to ! > */
2284 1, /* transform >= to ! < */
2285 1, /* transform != to !(a == b) */
2286 0, /* leave == */
2287 FALSE, /* Array initializer support. */
2288 0, /* no CSE cost estimation yet */
2289 _z80_builtins, /* builtin functions */
2290 GPOINTER, /* treat unqualified pointers as "generic" pointers */
2291 1, /* reset labelKey to 1 */
2292 1, /* globals & local statics allowed */
2293 9, /* Number of registers handled in the tree-decomposition-based register allocator in SDCCralloc.hpp */
2294 PORT_MAGIC
2297 PORT r800_port =
2299 TARGET_ID_R800,
2300 "r800",
2301 "R800", /* Target name */
2302 NULL, /* Processor name */
2304 glue,
2305 FALSE,
2306 NO_MODEL,
2307 NO_MODEL,
2308 NULL, /* model == target */
2310 { /* Assembler */
2311 _z80AsmCmd,
2312 NULL,
2313 "-plosgffwy", /* Options with debug */
2314 "-plosgffw", /* Options without debug */
2316 ".asm"
2318 { /* Linker */
2319 _z80LinkCmd, //NULL,
2320 NULL, //LINKCMD,
2321 NULL,
2322 ".rel",
2324 _crt, /* crt */
2325 _libs_r800, /* libs */
2327 { /* Peephole optimizer */
2328 _z80_defaultRules,
2329 z80instructionSize,
2330 NULL,
2331 NULL,
2332 NULL,
2333 z80notUsed,
2334 z80canAssign,
2335 z80notUsedFrom,
2336 z80symmParmStack,
2337 z80canJoinRegs,
2338 z80canSplitReg,
2340 /* Sizes: char, short, int, long, long long, near ptr, far ptr, gptr, func ptr, banked func ptr, bit, float, BitInt (in bits) */
2341 { 1, 2, 2, 4, 8, 2, 2, 2, 2, 2, 1, 4, 64 },
2342 /* tags for generic pointers */
2343 { 0x00, 0x40, 0x60, 0x80 }, /* far, near, xstack, code */
2345 "XSEG",
2346 "STACK",
2347 "CODE",
2348 "DATA",
2349 NULL, /* idata */
2350 NULL, /* pdata */
2351 NULL, /* xdata */
2352 NULL, /* bit */
2353 "RSEG (ABS)",
2354 "GSINIT",
2355 NULL, /* overlay */
2356 "GSFINAL",
2357 "HOME",
2358 NULL, /* xidata */
2359 NULL, /* xinit */
2360 NULL, /* const_name */
2361 "CABS (ABS)", /* cabs_name */
2362 "DABS (ABS)", /* xabs_name */
2363 NULL, /* iabs_name */
2364 "INITIALIZED", /* name of segment for initialized variables */
2365 "INITIALIZER", /* name of segment for copies of initialized variables in code space */
2366 NULL,
2367 NULL,
2368 1, /* CODE is read-only */
2369 false, // unqualified pointers cannot point to __sfr.
2370 1 /* No fancy alignments supported. */
2372 { NULL, NULL },
2373 1, /* ABI revision */
2374 { -1, 0, 0, 4, 0, 3, 0 },
2376 -1, /* shifts never use support routines */
2377 false, /* do not use support routine for int x int -> long multiplication */
2378 false, /* do not use support routine for unsigned long x unsigned char -> unsigned long long multiplication */
2380 { z80_emitDebuggerSymbol },
2382 8000, /* maxCount */
2383 2, /* sizeofElement */
2384 {6, 7, 8}, /* sizeofMatchJump[] - Assumes operand allocated to registers */
2385 {6, 9, 15}, /* sizeofRangeCompare[] - Assumes operand allocated to registers*/
2386 1, /* sizeofSubtract - Assumes use of a single inc or dec */
2387 9, /* sizeofDispatch - Assumes operand allocated to register e or c*/
2389 "_",
2390 _r800_init,
2391 _parseOptions,
2392 _z80_like_options,
2393 NULL,
2394 _finaliseOptions,
2395 _setDefaultOptions,
2396 z80_assignRegisters,
2397 _getRegName,
2398 _getRegByName,
2399 NULL,
2400 _keywords,
2401 _z80_genAssemblerStart,
2402 NULL, /* no genAssemblerEnd */
2403 0, /* no local IVT generation code */
2404 0, /* no genXINIT code */
2405 NULL, /* genInitStartup */
2406 _reset_regparm,
2407 _reg_parm,
2408 _process_pragma,
2409 NULL,
2410 _hasNativeMulFor,
2411 hasExtBitOp, /* hasExtBitOp */
2412 oclsExpense, /* oclsExpense */
2413 TRUE,
2414 TRUE, /* little endian */
2415 0, /* leave lt */
2416 0, /* leave gt */
2417 1, /* transform <= to ! > */
2418 1, /* transform >= to ! < */
2419 1, /* transform != to !(a == b) */
2420 0, /* leave == */
2421 FALSE, /* Array initializer support. */
2422 0, /* no CSE cost estimation yet */
2423 _z80_builtins, /* builtin functions */
2424 GPOINTER, /* treat unqualified pointers as "generic" pointers */
2425 1, /* reset labelKey to 1 */
2426 1, /* globals & local statics allowed */
2427 9, /* Number of registers handled in the tree-decomposition-based register allocator in SDCCralloc.hpp */
2428 PORT_MAGIC