📄 1750a.c
字号:
/* Subroutines for insn-output.c for MIL-STD-1750. Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. Contributed by O.M.Kellogg, DASA (kellogg@space.otn.dasa.de)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, 59 Temple Place - Suite 330,Boston, MA 02111-1307, USA. */#define __datalbl#include "config.h"#include <stdio.h>#include <string.h>#include "rtl.h"#include "tree.h"#include "expr.h"#define HAVE_cc0#include "conditions.h"#include "real.h"#include "regs.h"struct datalabel_array datalbl[DATALBL_ARRSIZ];int datalbl_ndx = -1;struct jumplabel_array jmplbl[JMPLBL_ARRSIZ];int jmplbl_ndx = -1;int label_pending = 0, program_counter = 0;enum section current_section = Normal;char *sectname[4] ={"Init", "Normal", "Konst", "Static"};intnotice_update_cc (exp) rtx exp;{ if (GET_CODE (exp) == SET) { enum rtx_code src_code = GET_CODE (SET_SRC (exp)); /* Jumps do not alter the cc's. */ if (SET_DEST (exp) == pc_rtx) return; /* Moving a register or constant into memory doesn't alter the cc's. */ if (GET_CODE (SET_DEST (exp)) == MEM && (src_code == REG || src_code == CONST_INT)) return; /* Function calls clobber the cc's. */ if (src_code == CALL) { CC_STATUS_INIT; return; } /* Emulated longword bit-ops leave cc's incorrect */ if (GET_MODE (SET_DEST (exp)) == HImode ? src_code == AND || src_code == IOR || src_code == XOR || src_code == NOT : 0) { CC_STATUS_INIT; return; } /* Tests and compares set the cc's in predictable ways. */ if (SET_DEST (exp) == cc0_rtx) { CC_STATUS_INIT; cc_status.value1 = SET_SRC (exp); return; } /* Anything else will set cc_status. */ cc_status.flags = CC_NO_OVERFLOW; cc_status.value1 = SET_SRC (exp); cc_status.value2 = SET_DEST (exp); return; } else if (GET_CODE (exp) == PARALLEL && GET_CODE (XVECEXP (exp, 0, 0)) == SET) { if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx) return; if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx) { CC_STATUS_INIT; cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0)); return; } CC_STATUS_INIT; } else { CC_STATUS_INIT; }}rtxfunction_arg (cum, mode, type, named) int cum; enum machine_mode mode; tree type; int named;{ int size; if (MUST_PASS_IN_STACK (mode, type)) return (rtx) 0; if (mode == BLKmode) size = int_size_in_bytes (type); else size = GET_MODE_SIZE (mode); if (cum + size < 12) return gen_rtx (REG, mode, cum); else return (rtx) 0;}doubleget_double (x) rtx x;{ union { double d; long i[2]; } du; du.i[0] = CONST_DOUBLE_LOW (x); du.i[1] = CONST_DOUBLE_HIGH (x); return du.d;}char *float_label (code, value) char code; double value;{ int i = 1; static char label[32]; char *p; label[0] = code; p = label + 1; sprintf (p, "%lf", value); while (*p) { *p = (*p == '+') ? 'p' : (*p == '-') ? 'm' : *p; p++; } return xstrdup (label);}char *movcnt_regno_adjust (op) rtx *op;{ static char outstr[80]; int op0r = REGNO (op[0]), op1r = REGNO (op[1]), op2r = REGNO (op[2]);#define dstreg op0r#define srcreg op1r#define cntreg op2r#define cntreg_1750 (op0r + 1) if (cntreg == cntreg_1750) sprintf (outstr, "mov r%d,r%d", op0r, op1r); else if (dstreg + 1 == srcreg && cntreg > srcreg) sprintf (outstr, "xwr r%d,r%d\n\tmov r%d,r%d", op2r, op1r, op0r, op2r); else if (dstreg == cntreg + 1) sprintf (outstr, "xwr r%d,r%d\n\tmov r%d,r%d", op0r, op2r, op2r, op1r); else if (dstreg == srcreg + 1) sprintf (outstr, "xwr r%d,r%d\n\txwr r%d,r%d\n\tmov r%d,r%d", op0r, op1r, op0r, op2r, op1r, op2r); else if (cntreg + 1 == srcreg) sprintf (outstr, "xwr r%d,r%d\n\txwr r%d,r%d\n\tmov r%d,r%d", op2r, op1r, op0r, op2r, op2r, op0r); else if (cntreg == srcreg + 1) sprintf (outstr, "xwr r%d,r%d\n\tmov r%d,r%d", op0r, op1r, op1r, op0r); else sprintf (outstr, "xwr r%d,r%d\n\tmov r%d,r%d\n\txwr r%d,r%d", op2r, cntreg_1750, op0r, op1r, op2r, cntreg_1750); return outstr;}char *mod_regno_adjust (instr, op) char *instr; rtx *op;{ static char outstr[40]; char *r = (!strncmp (instr, "dvr", 3) ? "r" : ""); int modregno_gcc = REGNO (op[3]), modregno_1750 = REGNO (op[0]) + 1; if (modregno_gcc == modregno_1750 || (reg_renumber != NULL && reg_renumber[modregno_gcc] >= 0 && reg_renumber[modregno_gcc] == reg_renumber[modregno_1750])) sprintf (outstr, "%s r%%0,%s%%2", instr, r); else sprintf (outstr, "lr r%d,r%d\n\t%s r%%0,%s%%2\n\txwr r%d,r%d", modregno_gcc, modregno_1750, instr, r, modregno_1750, modregno_gcc); return outstr;}/* Check if op is a valid memory operand for 1750A Load/Store instructions (memory indirection permitted.) */intmemop_valid (op) rtx op;{ static int recurred = 0; int valid_operand; if (GET_MODE (op) != Pmode && GET_MODE (op) != VOIDmode && GET_MODE (op) != QImode) return 0; switch (GET_CODE (op)) { case MEM: if (!recurred && GET_CODE (XEXP (op, 0)) == REG) return 1; case MINUS: case MULT: case DIV: return 0; case PLUS: recurred = 1; valid_operand = memop_valid (XEXP (op, 0)); if (valid_operand) valid_operand = memop_valid (XEXP (op, 1)); recurred = 0; return valid_operand; case REG: if (REGNO (op) > 0) return 1; return 0; case CONST: case CONST_INT: case SYMBOL_REF: case SUBREG: return 1; default: printf ("memop_valid: code=%d\n", (int) GET_CODE (op)); return 1; }}/* predicate for the MOV instruction: */intmov_memory_operand (op, mode) rtx op; enum machine_mode mode;{ return (GET_CODE (op) == MEM && GET_CODE (XEXP (op, 0)) == REG);}/* predicate for the STC instruction: */intsmall_nonneg_const (op, mode) rtx op; enum machine_mode mode;{ if (GET_CODE (op) == CONST_INT && INTVAL (op) >= 0 && INTVAL (op) <= 15) return 1; return 0;}/* predicate for constant zero: */intzero_operand (op, mode) rtx op; enum machine_mode mode;{ return op == CONST0_RTX (mode);}/* predicate for 1750 `B' addressing mode (Base Register with Offset) memory operand */intb_mode_operand (op) rtx op;{ if (GET_CODE (op) == MEM) { rtx inner = XEXP (op, 0); if (GET_CODE (inner) == REG && REG_OK_FOR_INDEX_P (inner)) return 1; if (GET_CODE (inner) == PLUS) { rtx plus_op0 = XEXP (inner, 0); if (GET_CODE (plus_op0) == REG && REG_OK_FOR_INDEX_P (plus_op0)) { rtx plus_op1 = XEXP (inner, 1); if (GET_CODE (plus_op1) == CONST_INT && INTVAL (plus_op1) >= 0 && INTVAL (plus_op1) <= 255) return 1; } } } return 0;}/* Decide whether to output a conditional jump as a "Jump Conditional" or as a "Branch Conditional": */intfind_jmplbl (labelnum) int labelnum;{ int i, found = 0; for (i = 0; i <= jmplbl_ndx; i++) if (labelnum == jmplbl[i].num) { found = 1; break; } if (found) return i; return -1;}char *branch_or_jump (condition, targetlabel_number) char *condition; int targetlabel_number;{ static char buf[30]; int index; if ((index = find_jmplbl (targetlabel_number)) >= 0) if (program_counter - jmplbl[index].pc < 128) { sprintf (buf, "b%s %%l0", condition); return buf; } sprintf (buf, "jc %s,%%l0", condition); return buf;}intunsigned_comparison_operator (insn) rtx insn;{ switch (GET_CODE (insn)) { case GEU: case GTU: case LEU: case LTU:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -