📄 tm-tower-as.h
字号:
/* Definitions of target machine for GNU compiler. Copyright (C) 1990 Free Software Foundation, Inc. Written by Robert Andersson, International Systems, Oslo, Norway. Send bug reports, questions and improvements to ra@intsys.no. For NCR Tower 32/4x0 and 32/6x0 running System V Release 3. This file outputs assembler source suitable for the native Tower as and with sdb debugging symbols. See tm-tower.h for more comments. This file was based on tm-m68k.h, tm-hp9k320.h and tm-3b1.h as of the 1.37.1 version.This file is part of GNU CC.GNU CC is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 1, or (at your option)any later version.GNU CC is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU CC; see the file COPYING. If not, write tothe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */#include "tm-tower.h"/* Define __HAVE_68881 in preprocessor only if -m68881 is specified. This will control the use of inline 68881 insns in certain macros. Also, define special define used to identify the Tower assembler. */#define CPP_SPEC "-D__TOWER_ASM__ %{m68881:-D__HAVE_68881__}"/* The startfiles and libraries depend on the -p and -m68881 options. The Tower does not support the -pg option. */#define STARTFILE_SPEC \"%{p:%{m68881:/usr/lib/fp/mcrt1.o}%{!m68881:/lib/mcrt1.o}} \ %{!p:%{m68881:/usr/lib/fp/crt1.o}%{!m68881:/lib/crt1.o}}"/* These four macros control how m68k.md is expanded. */#define MOTOROLA#define SGS#define SONY_ASM#define HPUX_ASM/* Turn on SDB debugging info. */#define SDB_DEBUGGING_INFO/* This is only useful if gdb is changed, but doesn't harm anyway. */#define ASM_IDENTIFY_GCC(FILE) \ fprintf (FILE, "gcc_compiled%%:\n")/* All the ASM_OUTPUT macros need to conform to the Tower as syntax. */#define ASM_OUTPUT_SOURCE_FILENAME(FILE, FILENAME) \ fprintf (FILE, "\tfile\t\"%s\"\n", FILENAME)#define ASM_OUTPUT_SOURCE_LINE(FILE, LINENO) \ fprintf (FILE, "\tln\t%d\n", \ (sdb_begin_function_line \ ? last_linenum - sdb_begin_function_line : 1))#define ASM_OUTPUT_IDENT(FILE, NAME) \ fprintf (FILE, "\tident\t\"%s\" \n", NAME)#define ASM_OUTPUT_ASCII(FILE,PTR,LEN) \ { register int sp = 0, lp = 0; \ fprintf (FILE, "\tbyte\t"); \ loop: \ if (PTR[sp] > ' ' && ! (PTR[sp] & 0x80) && PTR[sp] != '\\') \ { lp += 3; \ fprintf (FILE, "'%c", PTR[sp]); } \ else \ { lp += 5; \ fprintf (FILE, "0x%x", PTR[sp]); } \ if (++sp < LEN) \ { if (lp > 60) \ { lp = 0; \ fprintf (FILE, "\n\tbyte\t"); } \ else \ putc (',', FILE); \ goto loop; } \ putc ('\n', FILE); }/* Translate Motorola opcodes such as `jbeq' into SGS/Tower opcodes such as `beq.w'. Change `move' to `mov'. Change `cmpm' to `cmp'. Change `divsl' to `tdivs'. Change `divul' to `tdivu'. Change `ftst' to `ftest'. Change `fmove' to `fmov'. */#define ASM_OUTPUT_OPCODE(FILE, PTR) \{ if ((PTR)[0] == 'j' && (PTR)[1] == 'b') \ { ++(PTR); \ while (*(PTR) != ' ') \ { putc (*(PTR), (FILE)); ++(PTR); } \ fprintf ((FILE), ".w"); } \ else if ((PTR)[0] == 'm' && (PTR)[1] == 'o' \ && (PTR)[2] == 'v' && (PTR)[3] == 'e') \ { fprintf ((FILE), "mov"); (PTR) += 4; } \ else if ((PTR)[0] == 'c' && (PTR)[1] == 'm' \ && (PTR)[2] == 'p' && (PTR)[3] == 'm') \ { fprintf ((FILE), "cmp"); (PTR) += 4; } \ else if ((PTR)[0] == 'd' && (PTR)[1] == 'i' \ && (PTR)[2] == 'v' && (PTR)[3] == 's' \ && (PTR)[4] == 'l') \ { fprintf ((FILE), "tdivs"); (PTR) += 5; } \ else if ((PTR)[0] == 'd' && (PTR)[1] == 'i' \ && (PTR)[2] == 'v' && (PTR)[3] == 'u' \ && (PTR)[4] == 'l') \ { fprintf ((FILE), "tdivu"); (PTR) += 5; } \ else if ((PTR)[0] == 'f' && (PTR)[1] == 't' \ && (PTR)[2] == 's' && (PTR)[3] == 't') \ { fprintf ((FILE), "ftest"); (PTR) += 4; } \ else if ((PTR)[0] == 'f' && (PTR)[1] == 'm' \ && (PTR)[2] == 'o' && (PTR)[3] == 'v' \ && (PTR)[4] == 'e') \ { fprintf ((FILE), "fmov"); (PTR) += 5; } \}/* Override parts of tm-m68k.h to fit the Tower assembler. This section needs to track changes done to tm-m68k.h in the future. */#undef TARGET_VERSION#define TARGET_VERSION fprintf (stderr, " (68k, Motorola/SGS/Tower32 syntax)");#undef BLOCK_PROFILER#undef FUNCTION_BLOCK_PROFILER#undef FUNCTION_PROFILER#define FUNCTION_PROFILER(FILE, LABEL_NO) \ fprintf (FILE, "\tmov.l &LP%%%d,%%a0\n\tjsr mcount%%\n", (LABEL_NO))/* The prologue is identical to the one in tm-m68k.h except that the assembler syntax is different. */#undef FUNCTION_PROLOGUE#define FUNCTION_PROLOGUE(FILE, SIZE) \{ register int regno; \ register int mask = 0; \ extern char call_used_regs[]; \ int fsize = ((SIZE) + 3) & -4; \ if (frame_pointer_needed) \ { if (TARGET_68020 || fsize < 0x8000) \ fprintf (FILE, "\tlink %%a6,&%d\n", -fsize); \ else \ fprintf (FILE, "\tlink %%a6,&0\n\tsub.l &%d,%%sp\n", fsize); } \ for (regno = 24; regno < 56; regno++) \ if (regs_ever_live[regno] && ! call_used_regs[regno]) \ fprintf(FILE, "\tfpmoved %s,-(%%sp)\n", \ reg_names[regno]); \ for (regno = 16; regno < 24; regno++) \ if (regs_ever_live[regno] && ! call_used_regs[regno]) \ mask |= 1 << (regno - 16); \ if ((mask & 0xff) != 0) \ fprintf (FILE, "\tfmovm &0x%x,-(%%sp)\n", mask & 0xff); \ mask = 0; \ for (regno = 0; regno < 16; regno++) \ if (regs_ever_live[regno] && ! call_used_regs[regno]) \ mask |= 1 << (15 - regno); \ if (frame_pointer_needed) \ mask &= ~ (1 << (15-FRAME_POINTER_REGNUM)); \ if (exact_log2 (mask) >= 0) \ fprintf (FILE, "\tmov.l %s,-(%%sp)\n", reg_names[15 - exact_log2 (mask)]); \ else if (mask) fprintf (FILE, "\tmovm.l &0x%x,-(%%sp)\n", mask); }/* The epilogue is identical to the one in tm-m68k.h except that: a) The assembler syntax is different. b) Pointers are returned both in %d0 and %a0. c) FUNCTION_EXTRA_EPILOGUE is not needed. */#undef FUNCTION_EPILOGUE#define FUNCTION_EPILOGUE(FILE, SIZE) \{ register int regno; \ register int mask, fmask; \ register int nregs; \ int offset, foffset, fpoffset; \ extern char call_used_regs[]; \ extern int current_function_pops_args; \ extern int current_function_args_size; \ extern int current_function_returns_pointer; \ int fsize = ((SIZE) + 3) & -4; \ int big = 0; \ nregs = 0; fmask = 0; fpoffset = 0; \ for (regno = 24 ; regno < 56 ; regno++) \ if (regs_ever_live[regno] && ! call_used_regs[regno]) \ nregs++; \ fpoffset = nregs*8; \ nregs = 0; \ for (regno = 16; regno < 24; regno++) \ if (regs_ever_live[regno] && ! call_used_regs[regno]) \ { nregs++; fmask |= 1 << (23 - regno); } \ foffset = fpoffset + nregs * 12; \ nregs = 0; mask = 0; \ if (frame_pointer_needed) regs_ever_live[FRAME_POINTER_REGNUM] = 0; \ for (regno = 0; regno < 16; regno++) \ if (regs_ever_live[regno] && ! call_used_regs[regno]) \ { nregs++; mask |= 1 << regno; } \ offset = foffset + nregs * 4; \ if (offset + fsize >= 0x8000 \ && frame_pointer_needed \ && (mask || fmask || fpoffset)) \ { fprintf (FILE, "\tmov.l &%d,%%a0\n", -fsize); \ fsize = 0, big = 1; } \ if (exact_log2 (mask) >= 0) { \ if (big) \ fprintf (FILE, "\tmov.l -%d(%%a6,%%a0.l),%s\n", \ offset + fsize, reg_names[exact_log2 (mask)]); \ else if (! frame_pointer_needed) \ fprintf (FILE, "\tmov.l (%%sp)+,%s\n", \ reg_names[exact_log2 (mask)]); \ else \ fprintf (FILE, "\tmov.l -%d(%%a6),%s\n", \ offset + fsize, reg_names[exact_log2 (mask)]); } \ else if (mask) { \ if (big) \ fprintf (FILE, "\tmovm.l -%d(%%a6,%%a0.l),&0x%x\n", \ offset + fsize, mask); \ else if (! frame_pointer_needed) \ fprintf (FILE, "\tmovm.l (%%sp)+,&0x%x\n", mask); \ else \ fprintf (FILE, "\tmovm.l -%d(%%a6),&0x%x\n", \ offset + fsize, mask); } \ if (fmask) { \ if (big) \ fprintf (FILE, "\tfmovm -%d(%%a6,%%a0.l),&0x%x\n", \ foffset + fsize, fmask); \ else if (! frame_pointer_needed) \ fprintf (FILE, "\tfmovm (%%sp)+,&0x%x\n", fmask); \ else \ fprintf (FILE, "\tfmovm -%d(%%a6),&0x%x\n", \ foffset + fsize, fmask); } \ if (fpoffset != 0) \ for (regno = 55; regno >= 24; regno--) \ if (regs_ever_live[regno] && ! call_used_regs[regno]) { \ if (big) \ fprintf(FILE, "\tfpmoved -%d(%%a6,%%a0.l),%s\n", \ fpoffset + fsize, reg_names[regno]); \ else if (! frame_pointer_needed) \ fprintf(FILE, "\tfpmoved (%%sp)+,%s\n", \ reg_names[regno]); \ else \ fprintf(FILE, "\tfpmoved -%d(%%a6),%s\n", \ fpoffset + fsize, reg_names[regno]); \ fpoffset -= 8; \ } \ if (current_function_returns_pointer) \ fprintf (FILE, "\tmov.l %%d0,%%a0\n"); \ if (frame_pointer_needed) \ fprintf (FILE, "\tunlk %%a6\n"); \ if (current_function_pops_args && current_function_args_size) \ fprintf (FILE, "\trtd &%d\n", current_function_args_size); \ else fprintf (FILE, "\trts\n"); }/* This is how to output an insn to push a register on the stack. It need not be very fast code. */#undef ASM_OUTPUT_REG_PUSH#define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \ fprintf (FILE, "\tmov.l %s,-(%%sp)\n", reg_names[REGNO])/* This is how to output an insn to pop a register from the stack. It need not be very fast code. */#undef ASM_OUTPUT_REG_POP#define ASM_OUTPUT_REG_POP(FILE,REGNO) \ fprintf (FILE, "\tmov.l (%%sp)+,%s\n", reg_names[REGNO])#undef ASM_FILE_START#define ASM_FILE_START(FILE) \( fprintf (FILE, "#NO_APP\n"), \ sdbout_filename ((FILE), main_input_filename))#undef TEXT_SECTION_ASM_OP#define TEXT_SECTION_ASM_OP "\ttext"#undef DATA_SECTION_ASM_OP#define DATA_SECTION_ASM_OP "\tdata"/* This says how to output an assembler line to define a global common symbol. We use SIZE rather than ROUNDED, as this is what the native cc does. */#undef ASM_OUTPUT_COMMON#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \( fputs ("\tcomm ", (FILE)), \ assemble_name ((FILE), (NAME)), \ fprintf ((FILE), ",%u\n", ((SIZE) == 0) ? (ROUNDED) : (SIZE)))/* This says how to output an assembler line to define a local common symbol. We use SIZE rather than ROUNDED, as this is what the native cc does. */#undef ASM_OUTPUT_LOCAL#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \( fputs ("\tlcomm ", (FILE)), \ assemble_name ((FILE), (NAME)), \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -