-/* Definitions of target machine for GNU compiler, MIL-STD-1750A version.
+/* Definitions of target machine for GNU compiler.
Copyright (C) 1994 Free Software Foundation, Inc.
- Contributed by O.M.Kellogg, Deutsche Aerospace (okellogg@salyko.cube.net).
+ Contributed by O.M.Kellogg, DASA (okellogg@salyko.cube.net).
This file is part of GNU CC.
/* SPECIAL ADDITION FOR MIL-STD-1750A by O.M.Kellogg, 15-Apr-1993 */
/* See file aux-output.c for the actual data instances. */
struct datalabel_array {
- char name[14];
+ char *name;
char value[14];
int size;
};
int pc;
int num;
};
-enum section { NREL, IREL, KREL, SREL };
+enum section { Init, Normal, Konst, Static };
#define DATALBL_ARRSIZ 256
#define JMPLBL_ARRSIZ 256
#ifndef __datalbl
extern int datalbl_ndx, jmplbl_ndx, label_pending, program_counter;
extern enum section current_section;
extern char *sectname[4];
+extern char *strdup(), *float_label();
#endif
/*--------------------------------------------------------------------*/
/* 1 for registers that have pervasive standard uses
and are not available for the register allocator.
- R15 is the 1750A stack pointer. R14 would be the frame
- pointer, but we'd like to try avoid using it if possible. */
+ R15 is the 1750A stack pointer. R14 is the frame pointer. */
#define FIXED_REGISTERS \
{ 0, 0, 0, 0, 0, 0, 0, 0, \
- 0, 0, 0, 0, 0, 0, 0, 1 }
+ 0, 0, 0, 0, 0, 0, 1, 1 }
/* 1 for registers not available across function calls.
These must include the FIXED_REGISTERS and also any
Zero means the frame pointer need not be set up (and parms
may be accessed via the stack pointer) in functions that seem suitable.
This is computed in `reload', in reload1.c. */
-#define FRAME_POINTER_REQUIRED 0
+#define FRAME_POINTER_REQUIRED 1
/* Base register for access to arguments of the function. */
#define ARG_POINTER_REGNUM 14
(C) == 'O' ? (VALUE) == 0 : 0)
/* Similar, but for floating constants, and defining letter 'G'.
- Here VALUE is the CONST_DOUBLE rtx itself.
- 1750 longfloat constant 0.0 is worth recognizing 'cause it's got
- all bits zero. */
-#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
- ((C) == 'G' && (VALUE) == CONST0_RTX(HFmode))
+ Here VALUE is the CONST_DOUBLE rtx itself. */
+#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) 0
/* Given an rtx X being reloaded into a reg required to be
in class CLASS, return the class of reg to actually use.
/* 1 if the tree TYPE should be returned in memory instead of in regs.
#define RETURN_IN_MEMORY(TYPE) \
- (int_size_in_bytes(TYPE) > 13)
+ (int_size_in_bytes(TYPE) > 12)
*/
/* Define this if PCC uses the nonreentrant convention for returning
and about the args processed so far, enough to enable macros
such as FUNCTION_ARG to determine where the next arg should go.
- For 1750A, this is a single integer, which is a number of bytes
+ For 1750A, this is a single integer, which is a number of words
of arguments scanned so far. */
#define CUMULATIVE_ARGS int
fprintf(FILE," (none)"); \
fprintf(FILE,"\n"); \
if (SIZE > 0) \
- fprintf(FILE,"\t%s R15,%d ; reserve local-variable space\n",\
- (SIZE <= 16 ? "SISP" : "SIM "),SIZE); \
- fprintf(FILE,"\tPSHM R14,R14 ; push old frame\n"); \
- fprintf(FILE,"\tLR R14,R15 ; set new frame\n"); \
+ fprintf(FILE,"\t%s\tr15,%d ; reserve local-variable space\n",\
+ (SIZE <= 16 ? "sisp" : "sim"),SIZE); \
+ fprintf(FILE,"\tpshm\tr14,r14 ; push old frame\n"); \
+ fprintf(FILE,"\tlr\tr14,r15 ; set new frame\n"); \
program_counter = 0; jmplbl_ndx = -1; \
}
#define FUNCTION_EPILOGUE(FILE, SIZE) { \
if (SIZE > 0) \
- fprintf(FILE,"\t%s R14,%d ; free up local-var space\n", \
- (SIZE <= 16 ? "AISP" : "AIM "),SIZE); \
- fprintf(FILE,"\tLR R15,R14 ; set stack to return addr\n");\
- fprintf(FILE,"\tURS R15\n"); }
+ fprintf(FILE,"\t%s\tr14,%d ; free up local-var space\n", \
+ (SIZE <= 16 ? "aisp" : "aim"),SIZE); \
+ fprintf(FILE,"\tlr\tr15,r14 ; set stack to return addr\n"); \
+ fprintf(FILE,"\tpopm\tr14,r14 ; restore prev. frame ptr\n"); \
+ fprintf(FILE,"\turs\tr15\n"); }
/* If the memory address ADDR is relative to the frame pointer,
correct it to be relative to the stack pointer instead.
ADDR should be a variable name. */
#define FIX_FRAME_POINTER_ADDRESS(ADDR,DEPTH) \
- fprintf(asm_out_file,"FIX_FRAME_POINTER_ADDRESS called, DEPTH=%d\n"), \
+ fprintf(stderr,"FIX_FRAME_POINTER_ADDRESS called, DEPTH=%d\n"), \
DEPTH), abort()
/* Store in the variable DEPTH the initial difference between the
/* Max number of bytes we can move from memory to memory
in one reasonably fast instruction. */
/* (was: "1750: not counting the MOV instruction") */
-#define MOVE_MAX 256
+#define MOVE_MAX 16
/* Define this if zero-extension is slow (more than one real instruction). */
/* #define SLOW_ZERO_EXTEND */
strcpy(name,p); \
if (p = (char *)strchr(name,'.')) \
*p = '\0'; \
- if (strlen(name) > 12) \
- name[12] = '\0'; /* TekAs can handle only up to 12 char. */ \
- fprintf(FILE,"\tNAME %s\n",name); \
- fprintf(FILE,"\tNOLIST\n\tINCLUDE \"M1750.INC\"\n\tLIST\n"); \
- fprintf(FILE,"\n\tSECTION SREL\n\tSECTION KREL\n\tSECTION IREL\n"); \
- fprintf(FILE,"\tSECTION NREL\n"); }
+ fprintf(FILE,"\tname %s\n",name); \
+ fprintf(FILE,"\tnolist\n\tinclude \"ms1750.inc\"\n\tlist\n\n"); \
+ fprintf(FILE,"\tglobal\t__main\n\n"); }
/* Output at end of assembler file.
For 1750, we copy the data labels accrued in datalbl[] from the Constants
- section (KREL) to the Writable-Data section (SREL). */
+ section (Konst) to the Writable-Data section (Static). */
#define ASM_FILE_END(FILE) \
do { \
if (datalbl_ndx >= 0) { \
int i, cum_size=0; \
- fprintf(FILE,"\n\tRESUME SREL\nINIT_SREL\n"); \
+ fprintf(FILE,"\n\tstatic\ninit_srel\n"); \
for (i = 0; i <= datalbl_ndx; i++) { \
- fprintf(FILE,"%s\t BLOCK %d\n", \
+ if (datalbl[i].name == NULL) \
+ { \
+ fprintf(stderr, "asm_file_end internal datalbl err\n"); \
+ exit (0); \
+ } \
+ fprintf(FILE,"%s \tblock %d\n", \
datalbl[i].name,datalbl[i].size); \
cum_size += datalbl[i].size; \
} \
- fprintf(FILE,"\n\tRESUME IREL\n"); \
- fprintf(FILE,"\tLIM R0,INIT_SREL\n"); /* destin. */ \
- fprintf(FILE,"\tLIM R1,%d\n",cum_size); /* count */ \
- fprintf(FILE,"\tLIM R2,K%s\n",datalbl[0].name); /* source */ \
- fprintf(FILE,"\tMOV R0,R2\n"); \
- fprintf(FILE,"\n\tRESUME NREL\n"); \
+ fprintf(FILE,"\n\tinit\n"); \
+ fprintf(FILE,"\tlim\tr0,init_srel\n"); /* destin. */ \
+ fprintf(FILE,"\tlim\tr1,%d\n",cum_size); /* count */ \
+ fprintf(FILE,"\tlim\tr2,K%s\n",datalbl[0].name); /* source */ \
+ fprintf(FILE,"\tmov\tr0,r2\n"); \
+ fprintf(FILE,"\n\tnormal\n"); \
datalbl_ndx = -1; /* reset stuff */ \
for (i = 0; i < DATALBL_ARRSIZ; i++) \
datalbl[i].size = 0; \
} \
- fprintf(FILE,"\n\tEND\n"); \
+ fprintf(FILE,"\n\tend\n"); \
} while (0)
/* Output to assembler file text saying following lines
may contain character constants, extra white space, comments, etc. */
-#define ASM_APP_ON "\n\tIF 0\n; by ASM_APP_ON\n"
+#define ASM_APP_ON "\n\tif 0\n; by ASM_APP_ON\n"
/* Output to assembler file text saying following lines
no longer contain unusual constructs. */
-#define ASM_APP_OFF "\n\tENDIF\n"
+#define ASM_APP_OFF "\n\tendif\n"
#define EXTRA_SECTIONS in_readonly_data
#define EXTRA_SECTION_FUNCTIONS \
void const_section() \
{ \
- fprintf(asm_out_file,"\tRESUME KREL\n"); \
- current_section = KREL; \
+ fprintf(asm_out_file,"\tkonst\n"); \
+ current_section = Konst; \
} \
check_section(enum section sect) \
{ \
if (current_section != sect) { \
- fprintf(asm_out_file,"\tRESUME %s\n",sectname[(int)sect]); \
+ fprintf(asm_out_file,"\t%s\n",sectname[(int)sect]); \
current_section = sect; \
} \
switch (sect) { \
- case NREL: \
+ case Init: \
+ case Normal: \
in_section = in_text; \
break; \
- case SREL: \
+ case Static: \
in_section = in_data; \
break; \
- case KREL: \
+ case Konst: \
in_section = in_readonly_data; \
break; \
} \
/* Function that switches to the read-only data section (optional) */
#define READONLY_DATA_SECTION const_section
+/* Output before program init section */
+#define INIT_SECTION_ASM_OP "\n\tinit ; init_section\n"
+
/* Output before program text section */
-#define TEXT_SECTION_ASM_OP "\n\tRESUME NREL ; text_section\n"
+#define TEXT_SECTION_ASM_OP "\n\tnormal ; text_section\n"
/* Output before writable data. */
-#define DATA_SECTION_ASM_OP "\n\tRESUME SREL ; data_section\n"
+#define DATA_SECTION_ASM_OP "\n\tstatic ; data_section\n"
/* How to refer to registers in assembler output.
This sequence is indexed by compiler's hard-register-number (see above). */
/****************** Assembler output formatting **********************/
-#define ASM_IDENTIFY_GCC(FILE)
+#define ASM_IDENTIFY_GCC(FILE) fputs ("; gcc2_compiled:\n", FILE)
#define ASM_COMMENT_START ";"
fprintf(FILE,"%s\n",NAME)
#define ASM_OUTPUT_OPCODE(FILE,PTR) do { \
+ while (*(PTR) != '\0' && *(PTR) != ' ') { \
+ putc (*(PTR), FILE); \
+ (PTR)++; \
+ } \
+ while (*(PTR) == ' ') \
+ (PTR)++; \
+ putc ('\t', FILE); \
program_counter += 2; \
} while (0)
such as the label on a static function or variable NAME. */
/* 1750 note: Labels are prefixed with a 'K'. This is because handling
has been changed for labels to be output in the "Constants" section
- (named "KREL"), and special initialization code takes care of copying
- the Const-section data into the writable data section (named "SREL").
- In the SREL section we therefore have the true label names (i.e.
+ (named "Konst"), and special initialization code takes care of copying
+ the Const-section data into the writable data section (named "Static").
+ In the Static section we therefore have the true label names (i.e.
not prefixed with 'K'). */
#define ASM_OUTPUT_LABEL(FILE,NAME) \
- do { if (NAME[0] == '.') \
- fprintf(FILE,"%s\n",NAME); \
- else { \
- if (strlen(NAME) > 11) NAME[11] = '\0'; \
- check_section(KREL); \
- fprintf(FILE,"K%s\n",NAME); \
- strcpy(datalbl[++datalbl_ndx].name,NAME); \
- label_pending = 1; \
- } \
+ do { if (NAME[0] == '.') { \
+ fprintf(stderr,"Oops! label %s can't begin with '.'\n",NAME); \
+ abort(); \
+ } \
+ else { \
+ check_section(Konst); \
+ fprintf(FILE,"K%s\n",NAME); \
+ datalbl[++datalbl_ndx].name = (char *)strdup (NAME); \
+ label_pending = 1; \
+ } \
} while (0)
defined for reference from other files. */
#define ASM_GLOBALIZE_LABEL(FILE,NAME) do { \
- check_section(NREL); \
- fputs ("\tGLOBAL ", FILE); assemble_name (FILE, NAME); \
- fputs (" ; export\n", FILE); } while (0)
+ fprintf (FILE, "\tglobal %s\t; export\n", NAME); \
+ } while (0)
/* This is how to output a reference to a user-level label named NAME.
`assemble_name' uses this. */
do { \
if (strcmp(PREFIX,"LC") == 0) { \
label_pending = 1; \
- sprintf(datalbl[++datalbl_ndx].name,"LC%d",NUM); \
- check_section(KREL); \
+ datalbl[++datalbl_ndx].name = (char *) malloc (9); \
+ sprintf(datalbl[datalbl_ndx].name,"LC%d",NUM); \
+ check_section(Konst); \
fprintf(FILE,"K%s%d\n",PREFIX,NUM); \
} \
else if (find_jmplbl(NUM) < 0) { \
/* This is how to output an assembler line defining a 1750A `float'
constant. */
-#define ASM_OUTPUT_FLOAT(FILE,VALUE) \
+#define ASM_OUTPUT_SHORT_FLOAT(FILE,VALUE) \
do { \
- char *tekfltstr = (char *)tekasm_float('E',VALUE); \
if (label_pending) \
label_pending = 0; \
else \
- strcpy(datalbl[++datalbl_ndx].name, \
- (char *)float_label('E',tekfltstr)); \
- strcpy(datalbl[datalbl_ndx].value,tekfltstr); \
+ datalbl[++datalbl_ndx].name = float_label('D',VALUE); \
+ sprintf (datalbl[datalbl_ndx].value, "%lf", (double) VALUE); \
datalbl[datalbl_ndx].size = 2; \
- fprintf (FILE, "\tDATAF %s\n",tekfltstr); \
+ fprintf (FILE, "\tdataf\t%lf\n",VALUE); \
} while(0)
/* This is how to output an assembler line defining a 1750A `double'
#define ASM_OUTPUT_THREE_QUARTER_FLOAT(FILE,VALUE) \
do { \
- char *tekfltstr = (char *)tekasm_float('D',VALUE); \
if (label_pending) \
label_pending = 0; \
else \
- strcpy(datalbl[++datalbl_ndx].name, \
- (char *)float_label('D',tekfltstr)); \
- strcpy(datalbl[datalbl_ndx].value,tekfltstr); \
+ datalbl[++datalbl_ndx].name = float_label('E',VALUE); \
+ sprintf (datalbl[datalbl_ndx].value, "%lf", VALUE); \
datalbl[datalbl_ndx].size = 3; \
- fprintf(FILE,"\tDATAF %s\n",tekfltstr); \
+ fprintf(FILE,"\tdataef\t%lf\n",VALUE); \
} while (0)
/* This is how to output an assembler line defining a string constant. */
} \
for (i = 0; i < LEN; i++) \
if (PTR[i] >= 32 && PTR[i] < 127) \
- fprintf(FILE,"\tDATA %d\t; '%c'\n",PTR[i],PTR[i]); \
+ fprintf(FILE,"\tdata\t%d\t; '%c'\n",PTR[i],PTR[i]); \
else \
- fprintf(FILE,"\tDATA %d\t; (ascii)\n",PTR[i]); \
+ fprintf(FILE,"\tdata\t%d\t; (ascii)\n",PTR[i]); \
} while (0)
/* This is how to output an assembler line defining an `int' constant. */
label_pending = 0; \
datalbl[datalbl_ndx].size = 1; \
} \
- fprintf(FILE, "\tDATA "); output_addr_const(FILE,VALUE); \
+ fprintf(FILE, "\tdata\t"); output_addr_const(FILE,VALUE); \
fprintf(FILE, "\n"); } while (0)
/* This is how to output an assembler line defining a `long int' constant. */
label_pending = 0; \
datalbl[datalbl_ndx].size = 2; \
} \
- fprintf(FILE, "\tDATAL "); output_addr_const(FILE,VALUE); \
+ fprintf(FILE, "\tdatal\t"); output_addr_const(FILE,VALUE); \
fprintf(FILE, "\n"); } while (0)
/* Likewise for `short' and `char' constants. */
/* This is how to output an element of a case-vector that is absolute. */
#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
- fprintf (FILE, "\tDATA L%d ;addr_vec_elt\n", VALUE)
+ fprintf (FILE, "\tdata\tL%d ;addr_vec_elt\n", VALUE)
/* This is how to output an element of a case-vector that is relative. */
#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, VALUE, REL) \
- fprintf (FILE, "\tDATA L%d-L%d ;addr_diff_elt\n", VALUE,REL)
+ fprintf (FILE, "\tdata\tL%d-L%d ;addr_diff_elt\n", VALUE,REL)
/* This is how to output an assembler line
that says to advance the location counter
to define a global common symbol. */
#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) do { \
- check_section(NREL); \
- fprintf(FILE,"\tGLOBAL "); assemble_name(FILE,NAME); \
- fprintf(FILE," ; common\n"); } while (0)
+ fprintf (FILE, "\tcommon %s,%d\n", NAME, SIZE); \
+ } while (0)
#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) do { \
- check_section(NREL); \
- fprintf(FILE,"\tGLOBAL "); assemble_name(FILE,NAME); \
- fprintf(FILE,"\t; external\n"); } while (0)
+ fprintf (FILE, "\tglobal %s\t; import\n", NAME); \
+ } while (0)
/* This says how to output an assembler line
to define a local common symbol. */
#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) do { \
- check_section(SREL); \
- fprintf(FILE,"%s \tBLOCK %d ; local\n",NAME,SIZE); \
+ check_section (Static); \
+ fprintf(FILE,"%s \tblock %d\t; local common\n",NAME,SIZE); \
} while (0)
/* Store in OUTPUT a string (made with alloca) containing
( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO)))
+#define ASM_OUTPUT_CONSTRUCTOR(FILE, NAME) do { \
+ fprintf(FILE, "\tinit\n\t"); assemble_name(NAME); \
+ fprintf(FILE," ;constructor"); } while (0)
+
+#define ASM_OUTPUT_DESTRUCTOR(FILE, NAME) do { \
+ fprintf(FILE, "\tinit\n\t"); assemble_name(NAME); \
+ fprintf(FILE," ;destructor"); } while (0)
+
/* Define the parentheses used to group arithmetic operations
in assembler code. */