⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stormy16.c

📁 linux下的gcc编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
voidxstormy16_initialize_trampoline (addr, fnaddr, static_chain)     rtx addr;     rtx fnaddr;     rtx static_chain;{  rtx reg_addr = gen_reg_rtx (Pmode);  rtx temp = gen_reg_rtx (HImode);  rtx reg_fnaddr = gen_reg_rtx (HImode);  rtx reg_addr_mem;  reg_addr_mem = gen_rtx_MEM (HImode, reg_addr);      emit_move_insn (reg_addr, addr);  emit_move_insn (temp, GEN_INT (0x3130 | STATIC_CHAIN_REGNUM));  emit_move_insn (reg_addr_mem, temp);  emit_insn (gen_addhi3 (reg_addr, reg_addr, const2_rtx));  emit_move_insn (temp, static_chain);  emit_move_insn (reg_addr_mem, temp);  emit_insn (gen_addhi3 (reg_addr, reg_addr, const2_rtx));  emit_move_insn (reg_fnaddr, fnaddr);  emit_move_insn (temp, reg_fnaddr);  emit_insn (gen_andhi3 (temp, temp, GEN_INT (0xFF)));  emit_insn (gen_iorhi3 (temp, temp, GEN_INT (0x0200)));  emit_move_insn (reg_addr_mem, temp);  emit_insn (gen_addhi3 (reg_addr, reg_addr, const2_rtx));  emit_insn (gen_lshrhi3 (reg_fnaddr, reg_fnaddr, GEN_INT (8)));  emit_move_insn (reg_addr_mem, reg_fnaddr);}/* Create an RTX representing the place where a function returns a   value of data type VALTYPE.  VALTYPE is a tree node representing a   data type.  Write `TYPE_MODE (VALTYPE)' to get the machine mode   used to represent that type.  On many machines, only the mode is   relevant.  (Actually, on most machines, scalar values are returned   in the same place regardless of mode).   If `PROMOTE_FUNCTION_RETURN' is defined, you must apply the same promotion   rules specified in `PROMOTE_MODE' if VALTYPE is a scalar type.   If the precise function being called is known, FUNC is a tree node   (`FUNCTION_DECL') for it; otherwise, FUNC is a null pointer.  This makes it   possible to use a different value-returning convention for specific   functions when all their calls are known.   `FUNCTION_VALUE' is not used for return vales with aggregate data types,   because these are returned in another way.  See `STRUCT_VALUE_REGNUM' and   related macros.  */rtxxstormy16_function_value (valtype, func)     tree valtype;     tree func ATTRIBUTE_UNUSED;{  enum machine_mode mode;  mode = TYPE_MODE (valtype);  PROMOTE_MODE (mode, 0, valtype);  return gen_rtx_REG (mode, RETURN_VALUE_REGNUM);}/* A C compound statement that outputs the assembler code for a thunk function,   used to implement C++ virtual function calls with multiple inheritance.  The   thunk acts as a wrapper around a virtual function, adjusting the implicit   object parameter before handing control off to the real function.   First, emit code to add the integer DELTA to the location that contains the   incoming first argument.  Assume that this argument contains a pointer, and   is the one used to pass the `this' pointer in C++.  This is the incoming   argument *before* the function prologue, e.g. `%o0' on a sparc.  The   addition must preserve the values of all other incoming arguments.   After the addition, emit code to jump to FUNCTION, which is a   `FUNCTION_DECL'.  This is a direct pure jump, not a call, and does not touch   the return address.  Hence returning from FUNCTION will return to whoever   called the current `thunk'.   The effect must be as if @var{function} had been called directly   with the adjusted first argument.  This macro is responsible for   emitting all of the code for a thunk function;   TARGET_ASM_FUNCTION_PROLOGUE and TARGET_ASM_FUNCTION_EPILOGUE are   not invoked.   The THUNK_FNDECL is redundant.  (DELTA and FUNCTION have already been   extracted from it.)  It might possibly be useful on some targets, but   probably not.  */static voidxstormy16_asm_output_mi_thunk (file, thunk_fndecl, delta,			       vcall_offset, function)     FILE *file;     tree thunk_fndecl ATTRIBUTE_UNUSED;     HOST_WIDE_INT delta;     HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED;     tree function;{  int regnum = FIRST_ARGUMENT_REGISTER;    /* There might be a hidden first argument for a returned structure.  */  if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function))))    regnum += 1;    fprintf (file, "\tadd %s,#0x%x\n", reg_names[regnum], (int) delta & 0xFFFF);  fputs ("\tjmpf ", file);  assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));  putc ('\n', file);}/* Mark functions with SYMBOL_REF_FLAG.  */static voidxstormy16_encode_section_info (decl, first)     tree decl;     int first ATTRIBUTE_UNUSED;{  if (TREE_CODE (decl) == FUNCTION_DECL)    SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;}/* Output constructors and destructors.  Just like    default_named_section_asm_out_* but don't set the sections writable.  */#undef TARGET_ASM_CONSTRUCTOR#define TARGET_ASM_CONSTRUCTOR xstormy16_asm_out_constructor#undef TARGET_ASM_DESTRUCTOR#define TARGET_ASM_DESTRUCTOR xstormy16_asm_out_destructorstatic voidxstormy16_asm_out_destructor (symbol, priority)     rtx symbol;     int priority;{  const char *section = ".dtors";  char buf[16];  /* ??? This only works reliably with the GNU linker.   */  if (priority != DEFAULT_INIT_PRIORITY)    {      sprintf (buf, ".dtors.%.5u",	       /* Invert the numbering so the linker puts us in the proper		  order; constructors are run from right to left, and the		  linker sorts in increasing order.  */	       MAX_INIT_PRIORITY - priority);      section = buf;    }  named_section_flags (section, 0);  assemble_align (POINTER_SIZE);  assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);}static voidxstormy16_asm_out_constructor (symbol, priority)     rtx symbol;     int priority;{  const char *section = ".ctors";  char buf[16];  /* ??? This only works reliably with the GNU linker.   */  if (priority != DEFAULT_INIT_PRIORITY)    {      sprintf (buf, ".ctors.%.5u",	       /* Invert the numbering so the linker puts us in the proper		  order; constructors are run from right to left, and the		  linker sorts in increasing order.  */	       MAX_INIT_PRIORITY - priority);      section = buf;    }  named_section_flags (section, 0);  assemble_align (POINTER_SIZE);  assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);}/* Print a memory address as an operand to reference that memory location.  */voidxstormy16_print_operand_address (file, address)     FILE * file;     rtx    address;{  HOST_WIDE_INT offset;  int pre_dec, post_inc;  /* There are a few easy cases.  */  if (GET_CODE (address) == CONST_INT)    {      fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (address) & 0xFFFF);      return;    }    if (CONSTANT_P (address) || GET_CODE (address) == CODE_LABEL)    {      output_addr_const (file, address);      return;    }    /* Otherwise, it's hopefully something of the form      (plus:HI (pre_dec:HI (reg:HI ...)) (const_int ...))  */  if (GET_CODE (address) == PLUS)    {      if (GET_CODE (XEXP (address, 1)) != CONST_INT)	abort ();      offset = INTVAL (XEXP (address, 1));      address = XEXP (address, 0);    }  else    offset = 0;  pre_dec = (GET_CODE (address) == PRE_DEC);  post_inc = (GET_CODE (address) == POST_INC);  if (pre_dec || post_inc)    address = XEXP (address, 0);    if (GET_CODE (address) != REG)    abort ();  fputc ('(', file);  if (pre_dec)    fputs ("--", file);  fputs (reg_names [REGNO (address)], file);  if (post_inc)    fputs ("++", file);  if (offset != 0)    {      fputc (',', file);      fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);    }  fputc (')', file);}/* Print an operand to an assembler instruction.  */voidxstormy16_print_operand (file, x, code)     FILE * file;     rtx    x;     int    code;{  switch (code)    {    case 'B':	/* There is either one bit set, or one bit clear, in X.	   Print it preceded by '#'.  */      {	HOST_WIDE_INT xx = 1;	HOST_WIDE_INT l;	if (GET_CODE (x) == CONST_INT)	  xx = INTVAL (x);	else	  output_operand_lossage ("`B' operand is not constant");		l = exact_log2 (xx);	if (l == -1)	  l = exact_log2 (~xx);	if (l == -1)	  output_operand_lossage ("`B' operand has multiple bits set");		fputs (IMMEDIATE_PREFIX, file);	fprintf (file, HOST_WIDE_INT_PRINT_DEC, l);	return;      }    case 'C':      /* Print the symbol without a surrounding @fptr().  */      if (GET_CODE (x) == SYMBOL_REF)	assemble_name (file, XSTR (x, 0));      else if (GET_CODE (x) == LABEL_REF)	output_asm_label (x);      else	xstormy16_print_operand_address (file, x);      return;    case 'o':    case 'O':      /* Print the immediate operand less one, preceded by '#'.           For 'O', negate it first.  */      {	HOST_WIDE_INT xx = 0;		if (GET_CODE (x) == CONST_INT)	  xx = INTVAL (x);	else	  output_operand_lossage ("`o' operand is not constant");		if (code == 'O')	  xx = -xx;		fputs (IMMEDIATE_PREFIX, file);	fprintf (file, HOST_WIDE_INT_PRINT_DEC, xx - 1);	return;      }    case 0:      /* Handled below.  */      break;          default:      output_operand_lossage ("xstormy16_print_operand: unknown code");      return;    }  switch (GET_CODE (x))    {    case REG:      fputs (reg_names [REGNO (x)], file);      break;    case MEM:      xstormy16_print_operand_address (file, XEXP (x, 0));      break;    default:      /* Some kind of constant or label; an immediate operand,         so prefix it with '#' for the assembler.  */      fputs (IMMEDIATE_PREFIX, file);      output_addr_const (file, x);      break;    }  return;}/* Expander for the `casesi' pattern.   INDEX is the index of the switch statement.   LOWER_BOUND is a CONST_INT that is the value of INDEX corresponding     to the first table entry.   RANGE is the number of table entries.   TABLE is an ADDR_VEC that is the jump table.   DEFAULT_LABEL is the address to branch to if INDEX is outside the     range LOWER_BOUND to LOWER_BOUND+RANGE-1.*/void xstormy16_expand_casesi (index, lower_bound, range, table, default_label)     rtx index;     rtx lower_bound;     rtx range;     rtx table;     rtx default_label;{  HOST_WIDE_INT range_i = INTVAL (range);  rtx int_index;  /* This code uses 'br', so it can deal only with tables of size up to     8192 entries.  */  if (range_i >= 8192)    sorry ("switch statement of size %lu entries too large", 	   (unsigned long) range_i);  index = expand_binop (SImode, sub_optab, index, lower_bound, NULL_RTX, 0,			OPTAB_LIB_WIDEN);  emit_cmp_and_jump_insns (index, range, GTU, NULL_RTX, SImode, 1,			   default_label);  int_index = gen_lowpart_common (HImode, index);  emit_insn (gen_ashlhi3 (int_index, int_index, GEN_INT (2)));  emit_jump_insn (gen_tablejump_pcrel (int_index, table));}/* Output an ADDR_VEC.  It is output as a sequence of 'jmpf'   instructions, without label or alignment or any other special   constructs.  We know that the previous instruction will be the   `tablejump_pcrel' output above.   TODO: it might be nice to output 'br' instructions if they could   all reach.  */voidxstormy16_output_addr_vec (file, label, table)     FILE *file;     rtx label ATTRIBUTE_UNUSED;     rtx table;{   int vlen, idx;    function_section (current_function_decl);  vlen = XVECLEN (table, 0);  for (idx = 0; idx < vlen; idx++)    {      fputs ("\tjmpf ", file);      output_asm_label (XEXP (XVECEXP (table, 0, idx), 0));      fputc ('\n', file);    }}/* Expander for the `call' patterns.   INDEX is the index of the switch statement.   LOWER_BOUND is a CONST_INT that is the value of INDEX corresponding     to the first table entry.   RANGE is the number of table entries.   TABLE is an ADDR_VEC that is the jump table.   DEFAULT_LABEL is the address to branch to if INDEX is outside the     range LOWER_BOUND to LOWER_BOUND+RANGE-1.*/void xstormy16_expand_call (retval, dest, counter)     rtx retval;     rtx dest;     rtx counter;{  rtx call, temp;  enum machine_mode mode;  if (GET_CODE (dest) != MEM)    abort ();  dest = XEXP (dest, 0);  if (! CONSTANT_P (dest)      && GET_CODE (dest) != REG)    dest = force_reg (Pmode, dest);    if (retval == NULL)    mode = VOIDmode;  else    mode = GET_MODE (retval);  call = gen_rtx_CALL (mode, gen_rtx_MEM (FUNCTION_MODE, dest),		       counter);  if (retval)    call = gen_rtx_SET (VOIDmode, retval, call);    if (! CONSTANT_P (dest))    {      temp = gen_reg_rtx (HImode);      emit_move_insn (temp, const0_rtx);    }  else    temp = const0_rtx;    call = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, call, 						gen_rtx_USE (VOIDmode, temp)));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -