/* ** DJ's 16-bit Intel i86 attempt */ /* Run-time Target Specification */ #define CPP_PREDEFINES "-Di86 -Dmsdos" extern int target_flags; #define TARGET_VERSION fprintf(stderr, " (i86, DOS, DJ)"); #define TARGET_SWITCHES \ { SUBTARGET_SWITCHES \ { "", 0 }} #define TARGET_OPTIONS \ { { "something", 0 }, \ SUBTARGET_OPTIONS \ } #define SUBTARGET_SWITCHES #define SUBTARGET_OPTIONS /* Storage Layout */ #define BITS_BIG_ENDIAN 0 #define BYTES_BIG_ENDIAN 0 #define WORDS_BIG_ENDIAN 0 #define FLOAT_WORDS_BIG_ENDIAN 0 #define BITS_PER_UNIT 8 #define BITS_PER_WORD 16 #define UNITS_PER_WORD 2 #define POINTER_SIZE 16 #define PARM_BOUNDARY 16 #define STACK_BOUNDARY 16 #define FUNCTION_BOUNDARY 1 #define BIGGEST_ALIGNMENT 8 #define EMPTY_FIELD_BOUNDARY 8 #define STRICT_ALIGNMENT 0 /* Layout of Source Language Data Types */ #define INT_TYPE_SIZE 16 #define SHORT_TYPE_SIZE 16 #define LONG_TYPE_SIZE 32 #define CHAR_TYPE_SIZE 8 #define DEFAULT_SIGNED_CHAR 1 #define SIZE_TYPE "unsigned int" #define PTRDIFF_TYPE "int" #define TARGET_BELL 7 #define TARGET_BS 8 #define TARGET_TAB 9 #define TARGET_NEWLINE 10 #define TARGET_VT 11 #define TARGET_FF 12 #define TARGET_CR 13 /* Registers */ /* ax dx cx bx si di bp sp */ /* 0 1 2 3 4 5 6 7 */ /* Register Basics */ #define FIRST_PSEUDO_REGISTER 8 #define FIXED_REGISTERS { 0, 0, 0, 0, 0, 0, 0, 1 } #define CALL_USED_REGISTERS { 1, 1, 1, 0, 0, 0, 0, 1 } /* Order of Allocation of Registers */ #define REG_ALLOC_ORDER { 0, 1, 2, 3, 4, 5, 6, 7 } /* How Values Fit in Registers */ #define HARD_REGNO_NREGS(REGNO, MODE) ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) #define HARD_REGNO_MODE_OK(REGNO, MODE) ((REGNO) < 4 ? 1 : (int) (MODE) != (int) QImode) #define MODES_TIEABLE_P(MODE1, MODE2) ((MODE1) == (MODE2)) /* Register Classes */ #define SMALL_REGISTER_CLASSES 1 enum reg_class { NO_REGS, AREG, DREG, CREG, BREG, SIREG, DIREG, BPREG, AD_REGS, /* %ax/%dx for DImode */ Q_REGS, /* %ax %bx %cx %dx */ INDEX_REGS, /* %si %di */ BASE_REGS, /* %bx %bp */ GENERAL_REGS, /* %ax %bx %cx %dx %si %di */ ALL_REGS, LIM_REG_CLASSES }; #define N_REG_CLASSES (int)LIM_REG_CLASSES #define REG_CLASS_NAMES \ { "NO_REGS", \ "AREG", "DREG", "CREG", "BREG", \ "SIREG", "DIREG", "BPREG", \ "AD_REGS", \ "Q_REGS", \ "INDEX_REGS", \ "BASE_REGS", \ "GENERAL_REGS", \ "ALL_REGS" } #define REG_CLASS_CONTENTS \ { 0x00, \ 0x01, 0x02, 0x04, 0x08, \ 0x10, 0x20, 0x40, \ 0x03, \ 0x0f, \ 0x30, \ 0x48, \ 0xff, \ 0xff \ }; #define CLASS_LIKELY_SPILLED_P(CLASS) 0 extern enum reg_class regclass_map[]; /* smallest class containing REGNO */ #define REGNO_REG_CLASS(REGNO) (regclass_map[REGNO]) #define BASE_REG_CLASS BASE_REGS #define INDEX_REG_CLASS INDEX_REGS #define REG_CLASS_FROM_LETTER(c) i86_reg_class_from_letter(c) #define REGNO_OK_FOR_BASE_P(num) ((num) == 3 || (num) == 6) #define REGNO_OK_FOR_INDEX_P(num) ((num) == 4 || (num) == 5) #define PREFERRED_RELOAD_CLASS(X,CLASS) (GET_MODE(X) == QImode && !((CLASS)==AREG||(CLASS)==BREG||(CLASS)==CREG||(CLASS)==DREG||(CLASS)==AD_REGS) ? Q_REGS : (CLASS)) #define LIMIT_RELOAD_CLASS(MODE, CLASS) \ ((MODE) == QImode && ((CLASS) == ALL_REGS || (CLASS) == GENERAL_REGS) \ ? Q_REGS : (CLASS)) #define CLASS_MAX_NREGS(CLASS, MODE) \ ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) #define CONST_OK_FOR_LETTER_P(v, c) i86_const_ok_for_letter_p(v,c) #define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) 0 /* Basic Stack Layout */ /* Frame Layout */ #define STACK_GROWS_DOWNWARD 1 #define FRAME_GROWS_DOWNWARD 1 #define STARTING_FRAME_OFFSET 0 #define FIRST_PARM_OFFSET(f) 2 /* Registers That Address the Stack Frame */ #define STACK_POINTER_REGNUM 7 #define FRAME_POINTER_REGNUM 6 #define ARG_POINTER_REGNUM 6 /* Elimination */ #define FRAME_POINTER_REQUIRED 1 #define INITIAL_FRAME_POINTER_OFFSET(x) 0 /* Passing Function Arguments on the Stack */ #define PROMOTE_PROTOTYPES 1 #define PUSH_ROUNDING(n) (((n)+1)&(-2)) #define RETURN_POPS_ARGS(d,t,s) 0 /* Passing Arguments in Registers */ #define FUNCTION_ARG(c,m,t,n) 0 #define FUNCTION_ARG_PARTIAL_NREGS(c,m,t,n) 0 #define FUNCTION_ARG_PASS_BY_REFERENCE(c,m,y,n) 0 #define CUMULATIVE_ARGS int #define INIT_CUMULATIVE_ARGS(c,f,l) c = 0 #define FUNCTION_ARG_ADVANCE(c,m,t,n) #define FUNCTION_ARG_REGNO_P(r) 0 /* How Scalar Function Values Are Returned */ #define FUNCTION_VALUE(VALTYPE, FUNC) \ gen_rtx (REG, TYPE_MODE (VALTYPE), 0) #define FUNCTION_VALUE_REGNO_P(N) ((N) == 0) #define LIBCALL_VALUE(MODE) \ gen_rtx (REG, MODE, 0) #define FUNCTION_PROLOGUE(file, size) i86_function_prolog(file, size) #define FUNCTION_PROLOGUE(file, size) i86_function_prolog(file, size) #define EXIT_IGNORE_STACK 0 #define FUNCTION_EPILOGUE(file, size) i86_function_epilog(file, size) /* How Large Values Are Returned */ #define STRUCT_VALUE 0 #define STRUCT_VALUE_INCOMING 0 /* Addressing Modes */ extern int i86_valid_addr(); #define CONSTANT_ADDRESS_P(x) CONSTANT_P(x) #define MAX_REGS_PER_ADDRESS 2 #define REG_OK_FOR_BASE_P(x) (REGNO(x) == 3 && REGNO(x) == 6) #define REG_OK_FOR_INDEX_P(x) (REGNO(x) == 4 && REGNO(x) == 5) #define LEGITIMIZE_ADDRESS(x,o,m,w) #define LEGITIMATE_CONSTANT_P(X) 1 #define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) \ if (GET_CODE (ADDR) == POST_INC || GET_CODE (ADDR) == POST_DEC) goto LABEL #ifdef REG_OK_STRICT #define GO_IF_LEGITIMATE_ADDRESS(m,x,l) { if (i86_valid_addr(m,x,1)) goto l; } #else #define GO_IF_LEGITIMATE_ADDRESS(m,x,l) { if (i86_valid_addr(m,x,0)) goto l; } #endif /* Condition Code Status */ extern void i86_notice_update_cc(); #define NOTICE_UPDATE_CC(e,i) i86_notice_update_cc(e) /* Describing Relative Costs of Operations */ #define CONST_COSTS(x,c,o) case CONST_INT: case CONST: case LABEL_REF: case SYMBOL_REF: return 0; case CONST_DOUBLE: return 2; #define SLOW_BYTE_ACCESS 1 #define MEMORY_MOVE_COST(x) 4 #define NO_FUNCTION_CSE 1 #define NO_RECURSIVE_FUNCTION_CSE 1 /* Misc */ #define CASE_VECTOR_MODE HImode #define EASY_DIV_EXPR TRUNC_DIV_EXPR #define MOVE_MAX 2 #define Pmode HImode #define FUNCTION_MODE QImode #define NO_IMPLICIT_EXTERN_C 1 #define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1 /* Trampolines */ #define INITIALIZE_TRAMPOLINE #define TRAMPOLINE_SIZE 0 /* Dividing the Output into Sections */ #define TEXT_SECTION_ASM_OP "\tsegment text" #define DATA_SECTION_ASM_OP "\tsegment data" /* The Overall Framework of an Assembler File */ #define ASM_FILE_START(f) i86_asm_file_start(f) #define ASM_FILE_END(f) i86_asm_file_end(f) #define ASM_IDENTIFY_GCC(f) i86_asm_identify_gcc(f) #define ASM_COMMENT_START ";" #define ASM_APP_ON "; asm app on\n" #define ASM_APP_OFF "; asm app off\n" #define ASM_OUTPUT_SOURCE_FILENAME(f,n) i86_asm_output_source_filename(f,n) #define ASM_OUTPUT_SOURCE_LINE(f,l) i86_asm_output_source_line(f,l) #define ASM_OUTPUT_EXTERNAL(f, d, s) i86_asm_output_external(f,d,s) #define ASM_OUTPUT_EXTERNAL_LIBCALL(f, s) i86_asm_output_external_libcall(f,s) /* Output of Data */ #define ASM_OUTPUT_INT(f,i) (fprintf(f, "\tdd\t"), output_addr_const(f,(i)), fprintf(f, "\n")) #define ASM_OUTPUT_SHORT(f,i) (fprintf(f, "\tdw\t"), output_addr_const(f,(i)), fprintf(f, "\n")) #define ASM_OUTPUT_CHAR(f,i) (fprintf(f, "\tdb\t"), output_addr_const(f,(i)), fprintf(f, "\n")) #define ASM_BYTE_OP "db" #define ASM_SHORT "\tdw" #define ASM_OUTPUT_BYTE(f,i) fprintf(f, "\t%s\t%d\n", ASM_BYTE_OP, i) #define ASM_OPEN_PAREN "(" #define ASM_CLOSE_PAREN ")" /* Output of Uninitialized Variables */ #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \ ( fputs ("\tglobal ", (FILE)), \ assemble_name ((FILE), (NAME)), \ fputs ("\n\tcommon ", (FILE)), \ assemble_name ((FILE), (NAME)), \ fprintf ((FILE), " %u\n", (ROUNDED))) #define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \ ( fputs ("\tcommon ", (FILE)), \ assemble_name ((FILE), (NAME)), \ fprintf ((FILE), " %u\n", (ROUNDED))) #define ASM_OUTPUT_LABEL(FILE,NAME) \ (assemble_name (FILE, NAME), fputs (":\n", FILE)) #define ASM_GLOBALIZE_LABEL(FILE,NAME) \ (fputs ("\n\tglobal\t", FILE), assemble_name (FILE, NAME), fputs ("\n", FILE)) #define ASM_OUTPUT_LABELREF(FILE,NAME) fprintf (FILE, "_%s", NAME) #define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \ fprintf (FILE, ".%s%d:\n", PREFIX, NUM) #define ASM_GENERATE_INTERNAL_LABEL(BUF,PREFIX,NUMBER) \ sprintf ((BUF), "*.%s%d", (PREFIX), (NUMBER)) #define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \ ( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \ sprintf ((OUTPUT), "%s.%d", (NAME), (LABELNO))) #define ASM_OUTPUT_ADDR_VEC_ELT(s,v) fprintf (s, "\tdw L%d\n", v) /* Output of Assembler Instructions */ #define REGISTER_NAMES {"ax", "dx", "cx", "bx", "si", "di", "bp", "sp"} #define PRINT_OPERAND(s,x,c) i86_print_operand(s,x,c) #define PRINT_OPERAND_ADDRESS(s,x) i86_print_operand_address(s,x) #define ASM_OUTPUT_REG_PUSH(s,r) fprintf(s, "push\t%s\n", REGISTER_NAMES[r]) #define ASM_OUTPUT_REG_POP(s,r) fprintf(s, "pop\t%s\n", REGISTER_NAMES[r]) #define STRUCT_VALUE_INCOMING 0 /* Alignment */ #define ASM_OUTPUT_ALIGN(s,p) #define ASM_OUTPUT_SKIP(s,p) fprintf(s, "\tresb\t%d\n", p) /* Profiling */ #define FUNCTION_PROFILER(f,l) /* Debugging */ #define DBX_REGISTER_NUMBER(regno) regno #define PREFERRED_DEBUGGING_TYPE DBX_DEBUG #define DBX_DEBUGGING_INFO #define ASM_STABS_OP "\t; stabs" #define ASM_STABD_OP "\t; stabd" #define ASM_STABN_OP "\t; stabn"