📄 gmicro.c
字号:
/* Subroutines for insn-output.c for the Gmicro. Ported by Masanobu Yuhara, Fujitsu Laboratories LTD. (yuhara@flab.fujitsu.co.jp) Copyright (C) 1990, 1991, 1997 Free Software Foundation, Inc.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 2, 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.Among other things, the copyrightnotice and this notice must be preserved on all copies.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, 59 Temple Place - Suite 330,Boston, MA 02111-1307, USA. */#include "config.h"#include <stdio.h>#include "rtl.h"#include "regs.h"#include "hard-reg-set.h"#include "real.h"#include "insn-config.h"#include "conditions.h"#include "insn-flags.h"#include "output.h"#include "insn-attr.h"extern char *rtx_name[];mypr (s, a1, a2, a3, a4, a5) char *s; int a1, a2, a3, a4, a5;{ fprintf (stderr, s, a1, a2, a3, a4, a5);}myprcode (i) int i;{ if (i < 0 || i > 90) fprintf (stderr, "code = %d\n", i); else fprintf (stderr, "code = %s\n", rtx_name[i]);}myabort (i) int i;{ fprintf (stderr, "myabort"); myprcode (i);}/* This is how to output an ascii string. *//* See ASM_OUTPUT_ASCII in gmicro.h. */output_ascii (file, p, size) FILE *file; char *p; int size;{ int i; int in_quote = 0; register int c; fprintf (file, "\t.sdata "); for (i = 0; i < size; i++) { c = p[i]; if (c >= ' ' && c < 0x7f) { if (!in_quote) { putc ('"', file); in_quote = 1; } putc (c, file); } else { if (in_quote) { putc ('"', file); in_quote = 0; } fprintf (file, "<%d>", c); } } if (in_quote) putc ('"', file); putc ('\n', file);}/* call this when GET_CODE (index) is MULT. */print_scaled_index (file, index) FILE *file; register rtx index;{ register rtx ireg; int scale; if (GET_CODE (XEXP (index, 0)) == REG) { ireg = XEXP (index, 0); scale = INTVAL (XEXP (index, 1)); } else { ireg = XEXP (index, 1); scale = INTVAL (XEXP (index, 0)); } if (scale == 1) fprintf (file, "%s", reg_names[REGNO (ireg)]); else fprintf (file, "%s*%d", reg_names[REGNO (ireg)], scale);} print_operand_address (file, addr) FILE *file; register rtx addr;{ register rtx xtmp0, xtmp1, breg, ixreg; int scale; int needcomma = 0; rtx offset; fprintf (file, "@"); retry: switch (GET_CODE (addr)) { case MEM: fprintf (file, "@"); addr = XEXP (addr, 0); goto retry; case REG: fprintf (file, "%s", reg_names[REGNO (addr)]); break; case MULT: print_scaled_index (file, addr); break; case PRE_DEC: fprintf (file, "-%s", reg_names[REGNO (XEXP (addr, 0))]); break; case POST_INC: fprintf (file, "%s+", reg_names[REGNO (XEXP (addr, 0))]); break; case PLUS: xtmp0 = XEXP (addr, 0); xtmp1 = XEXP (addr, 1); ixreg = 0; breg = 0; offset = 0; if (CONSTANT_ADDRESS_P (xtmp0)) { offset = xtmp0; breg = xtmp1; } else if (CONSTANT_ADDRESS_P (xtmp1)) { offset = xtmp1; breg = xtmp0; } else { goto NOT_DISP; } if (REG_CODE_BASE_P (breg)) goto PRINT_MEM; if (GET_CODE (breg) == MULT) { if (REG_CODE_INDEX_P (XEXP (breg, 0))) { ixreg = XEXP (breg, 0); scale = INTVAL (XEXP (breg, 1)); breg = 0; } else { ixreg = XEXP (breg, 1); scale = INTVAL (XEXP (breg, 0)); breg = 0; } goto PRINT_MEM; } /* GET_CODE (breg) must be PLUS here. */ xtmp0 = XEXP (breg, 0); xtmp1 = XEXP (breg, 1); if (REG_CODE_BASE_P (xtmp0)) { breg = xtmp0; xtmp0 = xtmp1; } else { breg = xtmp1; /* xtmp0 = xtmp0; */ } if (GET_CODE (xtmp0) == MULT) { if (REG_CODE_INDEX_P (XEXP (xtmp0, 0))) { ixreg = XEXP (xtmp0, 0); scale = INTVAL (XEXP (xtmp0, 1)); } else { ixreg = XEXP (xtmp0, 1); scale = INTVAL (XEXP (xtmp0, 0)); } } else { ixreg = xtmp0; scale = 1; } goto PRINT_MEM; NOT_DISP: if (REG_CODE_BASE_P (xtmp0)) { breg = xtmp0; xtmp0 = xtmp1; } else if (REG_CODE_BASE_P (xtmp1)) { breg = xtmp1; /* xtmp0 = xtmp0; */ } else goto NOT_BASE; if (REG_CODE_INDEX_P (xtmp0)) { ixreg = xtmp0; scale = 1; goto PRINT_MEM; } else if (CONSTANT_ADDRESS_P (xtmp0)) { offset = xtmp0; goto PRINT_MEM; } else if (GET_CODE (xtmp0) == MULT) { if (REG_CODE_INDEX_P (XEXP (xtmp0, 0))) { ixreg = XEXP (xtmp0, 0); scale = INTVAL (XEXP (xtmp0, 1)); } else { ixreg = XEXP (xtmp0, 1); scale = INTVAL (XEXP (xtmp0, 0)); } goto PRINT_MEM; } /* GET_CODE (xtmp0) must be PLUS. */ xtmp1 = XEXP (xtmp0, 1); xtmp0 = XEXP (xtmp0, 0); if (CONSTANT_ADDRESS_P (xtmp0)) { offset = xtmp0; xtmp0 = xtmp1; } else { offset = xtmp1; /* xtmp0 = xtmp0; */ } if (REG_CODE_INDEX_P (xtmp0)) { ixreg = xtmp0; } else { /* GET_CODE (xtmp0) must be MULT. */ if (REG_CODE_INDEX_P (XEXP (xtmp0, 0))) { ixreg = XEXP (xtmp0, 0); scale = INTVAL (XEXP (xtmp0, 1)); } else { ixreg = XEXP (xtmp0, 1); scale = INTVAL (XEXP (xtmp0, 0)); } } goto PRINT_MEM; NOT_BASE: if (GET_CODE (xtmp0) == PLUS) { ixreg = xtmp1; /* xtmp0 = xtmp0; */ } else { ixreg = xtmp0; xtmp0 = xtmp1; } if (REG_CODE_INDEX_P (ixreg)) { scale = 1; } else if (REG_CODE_INDEX_P (XEXP (ixreg, 0))) { scale = INTVAL (XEXP (ixreg, 1)); ixreg = XEXP (ixreg, 0); } else { /* was else if with no condition. OK ??? */ scale = INTVAL (XEXP (ixreg, 0)); ixreg = XEXP (ixreg, 1); } if (REG_CODE_BASE_P (XEXP (xtmp0, 0))) { breg = XEXP (xtmp0, 0); offset = XEXP (xtmp0, 1); } else { breg = XEXP (xtmp0, 1); offset = XEXP (xtmp0, 0); } PRINT_MEM: if (breg == 0 && ixreg == 0) { output_address (offset); break; } else if (ixreg == 0 && offset == 0) { fprintf (file, "%s", reg_names[REGNO (breg)]); break; } else { fprintf (file, "("); if (offset != 0) { output_addr_const (file, offset); needcomma = 1; } if (breg != 0) { if (needcomma) fprintf (file, ","); fprintf (file, "%s", reg_names[REGNO (breg)]); needcomma = 1; } if (ixreg != 0) { if (needcomma) fprintf (file, ","); fprintf (file, "%s", reg_names[REGNO (ixreg)]); if (scale != 1) fprintf (file,"*%d", scale); } fprintf (file, ")"); break; } default: output_addr_const (file, addr); }}/* Return a REG that occurs in ADDR with coefficient 1. ADDR can be effectively incremented by incrementing REG. */static rtxfind_addr_reg (addr) rtx addr;{ while (GET_CODE (addr) == PLUS) { if (GET_CODE (XEXP (addr, 0)) == REG) addr = XEXP (addr, 0); else if (GET_CODE (XEXP (addr, 1)) == REG) addr = XEXP (addr, 1); else if (GET_CODE (XEXP (addr, 0)) == PLUS) addr = XEXP (addr, 0); else if (GET_CODE (XEXP (addr, 1)) == PLUS) addr = XEXP (addr, 1); } if (GET_CODE (addr) == REG) return addr; return 0;} /* Return the best assembler insn template for moving operands[1] into operands[0] as a fullword. */static char *singlemove_string (operands) rtx *operands;{ if (FPU_REG_P (operands[0]) || FPU_REG_P (operands[1])) { if (GREG_P (operands[0]) || GREG_P (operands[1])) { myabort (101); /* Not Supported yet !! */ } else { return "fmov.s %1,%0"; } } return "mov.w %1,%0";}/* Output assembler code to perform a doubleword move insn with operands OPERANDS. */char *output_move_double (operands) rtx *operands;{ enum { REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP } optype0, optype1; rtx latehalf[2]; rtx addreg0 = 0, addreg1 = 0; /* First classify both operands. */ if (REG_P (operands[0])) optype0 = REGOP; else if (offsettable_memref_p (operands[0])) optype0 = OFFSOP; else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC) optype0 = POPOP; else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) optype0 = PUSHOP; else if (GET_CODE (operands[0]) == MEM) optype0 = MEMOP; else optype0 = RNDOP; if (REG_P (operands[1])) optype1 = REGOP; else if (CONSTANT_P (operands[1])) optype1 = CNSTOP; else if (offsettable_memref_p (operands[1])) optype1 = OFFSOP; else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC) optype1 = POPOP; else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC) optype1 = PUSHOP; else if (GET_CODE (operands[1]) == MEM) optype1 = MEMOP; else optype1 = RNDOP; /* Check for the cases that the operand constraints are not supposed to allow to happen. Abort if we get one, because generating code for these cases is painful. */ if (optype0 == RNDOP || optype1 == RNDOP) myabort (102);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -