clipper.c
来自「gcc3.2.1源代码」· C语言 代码 · 共 693 行 · 第 1/2 页
C
693 行
/* Subroutines for insn-output.c for Clipper Copyright (C) 1987, 1988, 1991, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. Contributed by Holger Teutsch (holger@hotbso.rhein-main.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 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.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 "system.h"#include "rtl.h"#include "regs.h"#include "hard-reg-set.h"#include "real.h"#include "insn-config.h"#include "conditions.h"#include "output.h"#include "insn-attr.h"#include "tree.h"#include "expr.h"#include "optabs.h"#include "libfuncs.h"#include "c-tree.h"#include "function.h"#include "flags.h"#include "recog.h"#include "tm_p.h"#include "target.h"#include "target-def.h"static void clipper_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));static void clipper_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));static void clix_asm_out_constructor PARAMS ((rtx, int));static void clix_asm_out_destructor PARAMS ((rtx, int));extern char regs_ever_live[];extern int frame_pointer_needed;static int frame_size;/* Initialize the GCC target structure. */#undef TARGET_ASM_ALIGNED_HI_OP#define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"#undef TARGET_ASM_FUNCTION_PROLOGUE#define TARGET_ASM_FUNCTION_PROLOGUE clipper_output_function_prologue#undef TARGET_ASM_FUNCTION_EPILOGUE#define TARGET_ASM_FUNCTION_EPILOGUE clipper_output_function_epiloguestruct gcc_target targetm = TARGET_INITIALIZER;/* Compute size of a clipper stack frame where 'lsize' is the required space for local variables. */intclipper_frame_size (lsize) int lsize;{ int i, size; /* total size of frame */ int save_size; save_size = 0; /* compute size for reg saves */ for (i = 16; i < 32; i++) if (regs_ever_live[i] && !call_used_regs[i]) save_size += 8; for (i = 0; i < 16; i++) if (regs_ever_live[i] && !call_used_regs[i]) save_size += 4; size = lsize + save_size; size = (size + 7) & ~7; /* align to 64 Bit */ return size;}/* Prologue and epilogue output Function is entered with pc pushed, i.e. stack is 32 bit aligned current_function_args_size == 0 means that the current function's args are passed totally in registers i.e fp is not used as ap. If frame_size is also 0 the current function does not push anything and can run with misaligned stack -> subq $4,sp / add $4,sp on entry and exit can be omitted. */static voidclipper_output_function_prologue (file, lsize) FILE *file; HOST_WIDE_INT lsize; /* size for locals */{ int i, offset; int size; frame_size = size = clipper_frame_size (lsize); if (frame_pointer_needed) { fputs ("\tpushw fp,sp\n", file); fputs ("\tmovw sp,fp\n", file); } else if (size != 0 || current_function_args_size != 0) { size += 4; /* keep stack aligned */ frame_size = size; /* must push data or access args */ } if (size) { if (size < 16) fprintf (file, "\tsubq $%d,sp\n", size); else fprintf (file, "\tsubi $%d,sp\n", size); /* register save slots are relative to sp, because we have small positive displacements and this works whether we have a frame pointer or not */ offset = 0; for (i = 16; i < 32; i++) if (regs_ever_live[i] && !call_used_regs[i]) { if (offset == 0) fprintf (file, "\tstord f%d,(sp)\n", i-16); else fprintf (file, "\tstord f%d,%d(sp)\n", i-16, offset); offset += 8; } for (i = 0; i < 16; i++) if (regs_ever_live[i] && !call_used_regs[i]) { if (offset == 0) fprintf (file, "\tstorw r%d,(sp)\n", i); else fprintf (file, "\tstorw r%d,%d(sp)\n", i, offset); offset += 4; } }}static voidclipper_output_function_epilogue (file, size) FILE *file; HOST_WIDE_INT size ATTRIBUTE_UNUSED;{ int i, offset; if (frame_pointer_needed) { offset = -frame_size; for (i = 16; i < 32; i++) if (regs_ever_live[i] && !call_used_regs[i]) { fprintf (file, "\tloadd %d(fp),f%d\n", offset, i-16); offset += 8; } for (i = 0; i < 16; i++) if (regs_ever_live[i] && !call_used_regs[i]) { fprintf (file, "\tloadw %d(fp),r%d\n", offset, i); offset += 4; } fputs ("\tmovw fp,sp\n\tpopw sp,fp\n\tret sp\n", file); } else /* no frame pointer */ { offset = 0; for (i = 16; i < 32; i++) if (regs_ever_live[i] && !call_used_regs[i]) { if (offset == 0) fprintf (file, "\tloadd (sp),f%d\n", i-16); else fprintf (file, "\tloadd %d(sp),f%d\n", offset, i-16); offset += 8; } for (i = 0; i < 16; i++) if (regs_ever_live[i] && !call_used_regs[i]) { if (offset == 0) fprintf (file, "\tloadw (sp),r%d\n", i); else fprintf (file, "\tloadw %d(sp),r%d\n", offset, i); offset += 4; } if (frame_size > 0) { if (frame_size < 16) fprintf (file, "\taddq $%d,sp\n", frame_size); else fprintf (file, "\taddi $%d,sp\n", frame_size); } fputs ("\tret sp\n", file); }}/* * blockmove * * clipper_movstr () */voidclipper_movstr (operands) rtx *operands;{ rtx dst,src,cnt,tmp,top,bottom=NULL_RTX,xops[3]; int align; int fixed; extern FILE *asm_out_file; dst = operands[0]; src = operands[1]; /* don't change this operands[2]; gcc 2.3.3 doesn't honor clobber note */ align = INTVAL (operands[3]); tmp = operands[4]; cnt = operands[5]; if (GET_CODE (operands[2]) == CONST_INT) /* fixed size move */ { if ((fixed = INTVAL (operands[2])) <= 0) abort (); if (fixed <16) output_asm_insn ("loadq %2,%5", operands); else output_asm_insn ("loadi %2,%5", operands); } else { fixed = 0; bottom = (rtx)gen_label_rtx (); /* need a bottom label */ xops[0] = cnt; xops[1] = bottom; output_asm_insn ("movw %2,%5", operands); /* count is scratch reg 5 */ output_asm_insn ("brle %l1", xops); } top = (rtx)gen_label_rtx (); /* top of loop label */ ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (top)); xops[0] = src; xops[1] = tmp; xops[2] = dst; if (fixed && (align & 0x3) == 0) /* word aligned move with known size */ { if (fixed >= 4) { rtx xops1[2]; output_asm_insn( "loadw %a0,%1\n\taddq $4,%0\n\tstorw %1,%a2\n\taddq $4,%2", xops); xops1[0] = cnt; xops1[1] = top; output_asm_insn ("subq $4,%0\n\tbrgt %l1", xops1); } if (fixed & 0x2) { output_asm_insn ("loadh %a0,%1\n\tstorh %1,%a2", xops); if (fixed & 0x1) output_asm_insn ("loadb 2%a0,%1\n\tstorb %1,2%a2", xops); } else if (fixed & 0x1) output_asm_insn ("loadb %a0,%1\n\tstorb %1,%a2", xops); } else { output_asm_insn( "loadb %a0,%1\n\taddq $1,%0\n\tstorb %1,%a2\n\taddq $1,%2", xops); xops[0] = cnt; xops[1] = top; output_asm_insn ("subq $1,%0\n\tbrgt %l1", xops); } if (fixed == 0) ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L", CODE_LABEL_NUMBER (bottom));}voidprint_operand_address (file, addr) FILE *file; register rtx addr;{ rtx op0,op1; switch (GET_CODE (addr)) { case REG: fprintf (file, "(%s)", reg_names[REGNO (addr)]); break; case PLUS: /* can be 'symbol + reg' or 'reg + reg' */ op0 = XEXP (addr, 0); op1 = XEXP (addr, 1); if (GET_CODE (op0) == REG && GET_CODE (op1) == REG) { fprintf (file, "[%s](%s)", reg_names[REGNO (op0)], reg_names[REGNO (op1)]); break; } if (GET_CODE (op0) == REG && CONSTANT_ADDRESS_P (op1)) { output_addr_const (file, op1); fprintf (file, "(%s)", reg_names[REGNO (op0)]); break; } if (GET_CODE (op1) == REG && CONSTANT_ADDRESS_P (op0)) { output_addr_const (file, op0); fprintf (file, "(%s)", reg_names[REGNO (op1)]); break; } abort (); /* Oh no */ default:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?