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
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 -------------------------------------------------------------------------*/
28 #include "SDCCsystem.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
[] = {
52 #include "peeph-z80.rul"
55 static char _r2k_defaultRules
[] = {
57 #include "peeph-r2k.rul"
60 static char _tlcs90_defaultRules
[] = {
62 #include "peeph-tlcs90.rul"
65 static char _sm83_defaultRules
[] = {
66 #include "peeph-sm83.rul"
70 static char _ez80_z80_defaultRules
[] = {
72 #include "peeph-z80.rul"
73 #include "peeph-ez80_z80.rul"
76 static char _z80n_defaultRules
[] = {
78 #include "peeph-z80.rul"
79 #include "peeph-z80n.rul"
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
},
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"},
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
},
152 // Determine if we can put parameters in registers
156 struct sym_link
*ftype
;
161 static char *_keywords
[] = {
173 "z88dk_params_offset",
177 static char *_keywordsgb
[] = {
190 static char *_keywordstlcs90
[] = {
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
;
226 z80_opts
.sub
= SUB_Z80
;
230 asm_addTree (&_gas_z80
);
233 asm_addTree (&_asxxxx_z80
);
244 z80_opts
.sub
= SUB_Z180
;
248 asm_addTree (&_gas_z80
);
251 asm_addTree (&_asxxxx_z80
);
262 z80_opts
.sub
= SUB_R2K
;
263 asm_addTree (&_asxxxx_r2k
);
272 z80_opts
.sub
= SUB_R2KA
;
273 asm_addTree (&_asxxxx_r2k
);
282 z80_opts
.sub
= SUB_R3KA
;
283 asm_addTree (&_asxxxx_r2k
);
292 z80_opts
.sub
= SUB_SM83
;
301 z80_opts
.sub
= SUB_TLCS90
;
302 asm_addTree (&_asxxxx_z80
);
309 _ez80_z80_init (void)
311 z80_opts
.sub
= SUB_EZ80_Z80
;
315 asm_addTree (&_gas_z80
);
318 asm_addTree (&_asxxxx_z80
);
329 z80_opts
.sub
= SUB_Z80N
;
330 asm_addTree (&_asxxxx_z80
);
339 z80_opts
.sub
= SUB_R800
;
340 asm_addTree (&_asxxxx_z80
);
347 _reset_regparm (struct sym_link
*ftype
)
350 _G
.regparam
.ftype
= ftype
;
351 if (IFFUNC_ISZ88DK_FASTCALL (ftype
) && IFFUNC_HASVARARGS (ftype
))
352 werror (E_Z88DK_FASTCALL_PARAMETERS
);
356 _reg_parm (sym_link
*l
, bool reentrant
)
358 if (IFFUNC_ISZ88DK_FASTCALL (_G
.regparam
.ftype
))
361 werror (E_Z88DK_FASTCALL_PARAMETERS
);
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);
380 do_pragma (int id
, const char *name
, const char *cp
)
382 struct pragma_token_s token
;
386 init_pragma_token (&token
);
392 struct dbuf_s buffer
;
394 dbuf_init (&buffer
, 128);
396 cp
= get_pragma_token (cp
, &token
);
407 case ASM_TYPE_ASXXXX
:
408 dbuf_printf (&buffer
, "CODE_%d", token
.val
.int_val
);
412 dbuf_printf (&buffer
, "ROMX,BANK[%d]", token
.val
.int_val
);
416 /* PENDING: what to use for ISAS? */
417 dbuf_printf (&buffer
, "CODE,BANK(%d)", token
.val
.int_val
);
421 dbuf_printf (&buffer
, ".ovly%04x", token
.val
.int_val
);
431 const char *str
= get_pragma_string (&token
);
433 dbuf_append_str (&buffer
, (0 == strcmp ("BASE", str
)) ? "HOME" : str
);
438 cp
= get_pragma_token (cp
, &token
);
439 if (TOKEN_EOL
!= token
.type
)
445 dbuf_c_str (&buffer
);
446 options
.code_seg
= (char *) dbuf_detach (&buffer
);
451 { /*.p.t.20030716 - adding pragma to manipulate z80 i/o port addressing modes */
454 cp
= get_pragma_token (cp
, &token
);
456 if (TOKEN_EOL
== token
.type
)
462 str
= get_pragma_string (&token
);
464 cp
= get_pragma_token (cp
, &token
);
465 if (TOKEN_EOL
!= token
.type
)
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
;
497 cp
= get_pragma_token (cp
, &token
);
498 if (token
.type
== TOKEN_EOL
)
504 segname
= Safe_strdup (get_pragma_string (&token
));
506 cp
= get_pragma_token (cp
, &token
);
507 if (token
.type
!= TOKEN_EOL
)
516 if (options
.code_seg
)
517 Safe_free (options
.code_seg
);
518 options
.code_seg
= segname
;
522 if (options
.const_seg
)
523 Safe_free (options
.const_seg
);
524 options
.const_seg
= segname
;
534 get_pragma_token (cp
, &token
);
537 werror (W_BAD_PRAGMA_ARGUMENTS
, name
);
539 free_pragma_token (&token
);
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
},
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
569 struct dbuf_s lnkFileName
;
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
);
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
);
599 buffer
= buildCmdLine (port
->linker
.cmd
, dstFileName
, NULL
, NULL
, NULL
, NULL
);
600 /* call the linker */
601 if (sdcc_system (buffer
))
604 perror ("Cannot exec linker");
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))
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
);
630 dbuf_printf (&buffer
, "CODE_%u", bank
);
632 dbuf_c_str (&buffer
);
633 options
.code_seg
= (char *) dbuf_detach (&buffer
);
636 else if (!strncmp (argv
[*i
], OPTION_BA
, sizeof (OPTION_BA
) - 1))
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
);
649 dbuf_printf (&buffer
, "DATA_%u", bank
);
651 dbuf_c_str (&buffer
);
652 options
.data_seg
= (char *) dbuf_detach (&buffer
);
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
;
687 else if (!strcmp (asmblr
, "asxxxx"))
689 _G
.asmType
= ASM_TYPE_ASXXXX
;
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
;
700 else if (!strcmp (asmblr
, "z80asm"))
702 port
->assembler
.externGlobal
= TRUE
;
703 asm_addTree (&_z80asm_z80
);
704 _G
.asmType
= ASM_TYPE_ISAS
;
707 else if (!strcmp (asmblr
, "gas"))
709 port
->assembler
.externGlobal
= TRUE
;
710 asm_addTree (&_gas_z80
);
711 _G
.asmType
= ASM_TYPE_GAS
;
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;
724 else if (!strcmp (portmode
, "z180"))
726 z80_opts
.port_mode
= 180;
730 else if (!strncmp (argv
[*i
], OPTION_EMIT_EXTERNS
, sizeof (OPTION_EMIT_EXTERNS
) - 1))
732 port
->assembler
.externGlobal
= 1;
745 if (options
.nostdlib
== FALSE
)
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
);
759 path
= buildCmdLine2 ("-l\"{port}.lib\"", s
);
760 dbuf_append_str (&dbuf
, 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)
781 setMainValue ("z80crt0", "\"crt0{objext}\"");
786 dbuf_init (&dbuf
, 128);
787 dbuf_printf (&dbuf
, "\"%s\"", path
);
788 setMainValue ("z80crt0", dbuf_c_str (&dbuf
));
789 dbuf_destroy (&dbuf
);
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
);
805 setMainValue ("z80outputtypeflag", "-Z");
806 setMainValue ("z80outext", ".gb");
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
);
827 _finaliseOptions (void)
829 port
->mem
.default_local_map
= data
;
830 port
->mem
.default_globl_map
= data
;
834 case ASM_TYPE_ASXXXX
:
835 asm_addTree (&_asxxxx_gb
);
838 asm_addTree (&_gas_gb
);
842 case ASM_TYPE_Z80ASM
:
853 _setDefaultOptions (void)
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;
866 options
.data_loc
= 0xc000;
867 else if (IS_RAB
) // Match default crt0
868 options
.data_loc
= 0xa000;
870 options
.data_loc
= 0x8000;
872 options
.out_fmt
= 'i'; /* Default output format is ihx */
879 policy is the function policy
880 params is the parameter format
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
889 rr - reentrant, caller saves
891 A combination of register short names and s to signify stack variables.
893 bds - first two args appear in BC and DE, the rest on the stack
894 s - all arguments are on the stack.
897 _mangleSupportFunctionName (const char *original
)
901 if (strstr (original
, "longlong"))
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
);
913 _getRegName (const struct reg_info
*reg
)
924 _getRegByName (const char *name
)
926 if (!strcmp (name
, "a"))
928 if (!strcmp (name
, "c"))
930 if (!strcmp (name
, "b"))
932 if (!strcmp (name
, "e"))
934 if (!strcmp (name
, "d"))
936 if (!strcmp (name
, "l"))
938 if (!strcmp (name
, "h"))
940 if (!strcmp (name
, "iyl"))
942 if (!strcmp (name
, "iyh"))
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
);
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;
967 if (IS_BITINT (OP_SYM_TYPE (IC_RESULT(ic
))) && SPEC_BITINTWIDTH (OP_SYM_TYPE (IC_RESULT(ic
))) % 8)
970 if (IS_LITERAL (left
))
972 else if (IS_LITERAL (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
)
978 /* Same for any multiplication with 8 bit result. */
979 else if (result_size
== 1 && !IS_SM83
)
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
)))
988 if (getSize (test
) <= 2)
994 /* Indicate which extended bit operations this port supports */
996 hasExtBitOp (int op
, sym_link
*left
, int right
)
1006 unsigned int lbits
= bitsForType (left
);
1011 if (right
% lbits
== 1 || right
% lbits
== lbits
- 1)
1013 if ((getSize (left
) <= 2 || getSize (left
) == 4) && lbits
== right
* 2)
1021 /* Indicate the expense of an access to an output storage class */
1023 oclsExpense (struct memmap
*oclass
)
1025 if (IN_FARSPACE (oclass
))
1032 //#define LINKCMD "sdld{port} -nf {dstfilename}"
1035 "sdld{port} -n -c -- {z80bases} -m -j" \
1037 " {z80extralibfiles} {z80extralibpaths}" \
1038 " {z80outputtypeflag} \"{linkdstfilename}\"" \
1040 " \"{dstfilename}{objext}\"" \
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
, };
1094 "Zilog Z80", /* Target name */
1095 NULL
, /* Processor name */
1101 NULL
, /* model == target */
1106 "-plosgffwy", /* Options with debug */
1107 "-plosgffw", /* Options without debug */
1112 _z80LinkCmd
, //NULL,
1116 1, /* needLinkerScript */
1118 _libs_z80
, /* libs */
1120 { /* Peephole optimizer */
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 */
1147 "GSINIT", /* static initialization */
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 */
1161 1, /* CODE is read-only */
1162 false, // unqualified pointers cannot point to __sfr.
1163 1 /* No fancy alignments supported. */
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
},
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*/
1189 z80_assignRegisters
,
1194 _z80_genAssemblerStart
,
1195 NULL
, /* no genAssemblerEnd */
1196 0, /* no local IVT generation code */
1197 0, /* no genXINIT code */
1198 NULL
, /* genInitStartup */
1204 hasExtBitOp
, /* hasExtBitOp */
1205 oclsExpense
, /* oclsExpense */
1207 TRUE
, /* little endian */
1210 1, /* transform <= to ! > */
1211 1, /* transform >= to ! < */
1212 1, /* transform != to !(a == b) */
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 */
1228 "Zilog Z180", /* Target name */
1229 NULL
, /* Processor name */
1235 NULL
, /* model == target */
1240 "-plosgffwy", /* Options with debug */
1241 "-plosgffw", /* Options without debug */
1246 _z80LinkCmd
, //NULL,
1252 _libs_z180
, /* libs */
1254 { /* Peephole optimizer */
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 */
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 */
1295 1, /* CODE is read-only */
1296 false, // unqualified pointers cannot point to __sfr.
1297 1 /* No fancy alignments supported. */
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*/
1323 z80_assignRegisters
,
1328 _z80_genAssemblerStart
,
1329 NULL
, /* no genAssemblerEnd */
1330 0, /* no local IVT generation code */
1331 0, /* no genXINIT code */
1332 NULL
, /* genInitStartup */
1338 hasExtBitOp
, /* hasExtBitOp */
1339 oclsExpense
, /* oclsExpense */
1341 TRUE
, /* little endian */
1344 1, /* transform <= to ! > */
1345 1, /* transform >= to ! < */
1346 1, /* transform != to !(a == b) */
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 */
1362 "Rabbit 2000", /* Target name */
1363 NULL
, /* Processor name */
1369 NULL
, /* model == target */
1374 "-plosgffwy", /* Options with debug */
1375 "-plosgffw", /* Options without debug */
1379 _z80LinkCmd
, //NULL,
1385 _libs_r2k
, /* libs */
1387 { /* Peephole optimizer */
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 */
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 */
1428 1, /* CODE is read-only */
1429 false, // unqualified pointers cannot point to __sfr.
1430 1 /* No fancy alignments supported. */
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*/
1456 z80_assignRegisters
,
1461 _z80_genAssemblerStart
,
1462 NULL
, /* no genAssemblerEnd */
1463 0, /* no local IVT generation code */
1464 0, /* no genXINIT code */
1465 NULL
, /* genInitStartup */
1471 hasExtBitOp
, /* hasExtBitOp */
1472 oclsExpense
, /* oclsExpense */
1474 TRUE
, /* little endian */
1477 1, /* transform <= to ! > */
1478 1, /* transform >= to ! < */
1479 1, /* transform != to !(a == b) */
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 */
1495 "Rabbit 2000A", /* Target name */
1496 NULL
, /* Processor name */
1502 NULL
, /* model == target */
1507 "-plosgffwy", /* Options with debug */
1508 "-plosgffw", /* Options without debug */
1513 _z80LinkCmd
, //NULL,
1519 _libs_r2ka
, /* libs */
1521 { /* Peephole optimizer */
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 */
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 */
1562 1, /* CODE is read-only */
1563 false, // unqualified pointers cannot point to __sfr.
1564 1 /* No fancy alignments supported. */
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*/
1590 z80_assignRegisters
,
1595 _z80_genAssemblerStart
,
1596 NULL
, /* no genAssemblerEnd */
1597 0, /* no local IVT generation code */
1598 0, /* no genXINIT code */
1599 NULL
, /* genInitStartup */
1605 hasExtBitOp
, /* hasExtBitOp */
1606 oclsExpense
, /* oclsExpense */
1608 TRUE
, /* little endian */
1611 1, /* transform <= to ! > */
1612 1, /* transform >= to ! < */
1613 1, /* transform != to !(a == b) */
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 */
1629 "Rabbit 3000A", /* Target name */
1630 NULL
, /* Processor name */
1636 NULL
, /* model == target */
1641 "-plosgffwy", /* Options with debug */
1642 "-plosgffw", /* Options without debug */
1647 _z80LinkCmd
, //NULL,
1653 _libs_r3ka
, /* libs */
1655 { /* Peephole optimizer */
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 */
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 */
1696 1, /* CODE is read-only */
1697 false, // unqualified pointers cannot point to __sfr.
1698 1 /* No fancy alignments supported. */
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*/
1724 z80_assignRegisters
,
1729 _z80_genAssemblerStart
,
1730 NULL
, /* no genAssemblerEnd */
1731 0, /* no local IVT generation code */
1732 0, /* no genXINIT code */
1733 NULL
, /* genInitStartup */
1739 hasExtBitOp
, /* hasExtBitOp */
1740 oclsExpense
, /* oclsExpense */
1742 TRUE
, /* little endian */
1745 1, /* transform <= to ! > */
1746 1, /* transform >= to ! < */
1747 1, /* transform != to !(a == b) */
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 */
1764 "Sharp SM83", /* Target name */
1771 NULL
, /* model == target */
1776 "-plosgffwy", /* Options with debug */
1777 "-plosgffw", /* Options without debug */
1780 NULL
/* no do_assemble function */
1789 _libs_sm83
, /* libs */
1791 { /* Peephole optimizer */
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 */
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 */
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. */
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*/
1860 z80_assignRegisters
,
1865 _z80_genAssemblerStart
,
1866 NULL
, /* no genAssemblerEnd */
1867 0, /* no local IVT generation code */
1868 0, /* no genXINIT code */
1869 NULL
, /* genInitStartup */
1875 hasExtBitOp
, /* hasExtBitOp */
1876 oclsExpense
, /* oclsExpense */
1878 TRUE
, /* little endian */
1881 1, /* transform <= to ! > */
1882 1, /* transform >= to ! < */
1883 1, /* transform != to !(a == b) */
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 */
1899 "Toshiba TLCS-90", /* Target name */
1900 NULL
, /* Processor name */
1906 NULL
, /* model == target */
1911 "-plosgffwy", /* Options with debug */
1912 "-plosgffw", /* Options without debug */
1917 _z80LinkCmd
, //NULL,
1923 _libs_tlcs90
, /* libs */
1925 { /* Peephole optimizer */
1926 _tlcs90_defaultRules
,
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 */
1952 "GSINIT", /* static initialization */
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 */
1966 1, /* CODE is read-only */
1967 false, // doesn't matter, as port has no __sfr anyway
1968 1 /* No fancy alignments supported. */
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*/
1994 z80_assignRegisters
,
1999 _z80_genAssemblerStart
,
2000 NULL
, /* no genAssemblerEnd */
2001 0, /* no local IVT generation code */
2002 0, /* no genXINIT code */
2003 NULL
, /* genInitStartup */
2009 hasExtBitOp
, /* hasExtBitOp */
2010 oclsExpense
, /* oclsExpense */
2012 TRUE
, /* little endian */
2015 1, /* transform <= to ! > */
2016 1, /* transform >= to ! < */
2017 1, /* transform != to !(a == b) */
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 */
2029 PORT ez80_z80_port
=
2033 "eZ80-Z80", /* Target name */
2034 NULL
, /* Processor name */
2040 NULL
, /* model == target */
2045 "-plosgffwy", /* Options with debug */
2046 "-plosgffw", /* Options without debug */
2051 _z80LinkCmd
, //NULL,
2057 _libs_ez80_z80
, /* libs */
2059 { /* Peephole optimizer */
2060 _ez80_z80_defaultRules
,
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 */
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 */
2100 1, /* CODE is read-only */
2101 false, // unqualified pointers cannot point to __sfr.
2102 1 /* No fancy alignments supported. */
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*/
2128 z80_assignRegisters
,
2133 _z80_genAssemblerStart
,
2134 NULL
, /* no genAssemblerEnd */
2135 0, /* no local IVT generation code */
2136 0, /* no genXINIT code */
2137 NULL
, /* genInitStartup */
2143 hasExtBitOp
, /* hasExtBitOp */
2144 oclsExpense
, /* oclsExpense */
2146 TRUE
, /* little endian */
2149 1, /* transform <= to ! > */
2150 1, /* transform >= to ! < */
2151 1, /* transform != to !(a == b) */
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 */
2167 "Z80N", /* Target name */
2168 NULL
, /* Processor name */
2174 NULL
, /* model == target */
2179 "-plosgffwy", /* Options with debug */
2180 "-plosgffw", /* Options without debug */
2185 _z80LinkCmd
, //NULL,
2191 _libs_z80n
, /* libs */
2193 { /* Peephole optimizer */
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 */
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 */
2234 1, /* CODE is read-only */
2235 false, // unqualified pointers cannot point to __sfr.
2236 1 /* No fancy alignments supported. */
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*/
2262 z80_assignRegisters
,
2267 _z80_genAssemblerStart
,
2268 NULL
, /* no genAssemblerEnd */
2269 0, /* no local IVT generation code */
2270 0, /* no genXINIT code */
2271 NULL
, /* genInitStartup */
2277 hasExtBitOp
, /* hasExtBitOp */
2278 oclsExpense
, /* oclsExpense */
2280 TRUE
, /* little endian */
2283 1, /* transform <= to ! > */
2284 1, /* transform >= to ! < */
2285 1, /* transform != to !(a == b) */
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 */
2301 "R800", /* Target name */
2302 NULL
, /* Processor name */
2308 NULL
, /* model == target */
2313 "-plosgffwy", /* Options with debug */
2314 "-plosgffw", /* Options without debug */
2319 _z80LinkCmd
, //NULL,
2325 _libs_r800
, /* libs */
2327 { /* Peephole optimizer */
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 */
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 */
2368 1, /* CODE is read-only */
2369 false, // unqualified pointers cannot point to __sfr.
2370 1 /* No fancy alignments supported. */
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*/
2396 z80_assignRegisters
,
2401 _z80_genAssemblerStart
,
2402 NULL
, /* no genAssemblerEnd */
2403 0, /* no local IVT generation code */
2404 0, /* no genXINIT code */
2405 NULL
, /* genInitStartup */
2411 hasExtBitOp
, /* hasExtBitOp */
2412 oclsExpense
, /* oclsExpense */
2414 TRUE
, /* little endian */
2417 1, /* transform <= to ! > */
2418 1, /* transform >= to ! < */
2419 1, /* transform != to !(a == b) */
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 */