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

📄 h8300.c

📁 gcc编译工具没有什么特别
💻 C
📖 第 1 页 / 共 5 页
字号:
	break;      }    default:      output_addr_const (file, addr);      break;    }}/* Output all insn addresses and their sizes into the assembly language   output file.  This is helpful for debugging whether the length attributes   in the md file are correct.  This is not meant to be a user selectable   option.  */voidfinal_prescan_insn (insn, operand, num_operands)     rtx insn, *operand;     int num_operands;{  /* This holds the last insn address.  */  static int last_insn_address = 0;  int uid = INSN_UID (insn);  if (TARGET_RTL_DUMP)    {      fprintf (asm_out_file, "\n****************");      print_rtl (asm_out_file, PATTERN (insn));      fprintf (asm_out_file, "\n");    }  if (TARGET_ADDRESSES)    {      fprintf (asm_out_file, "; 0x%x %d\n", insn_addresses[uid],	       insn_addresses[uid] - last_insn_address);      last_insn_address = insn_addresses[uid];    }}/* Prepare for an SI sized move.  */intdo_movsi (operands)     rtx operands[];{  rtx src = operands[1];  rtx dst = operands[0];  if (!reload_in_progress && !reload_completed)    {      if (!register_operand (dst, GET_MODE (dst)))	{	  rtx tmp = gen_reg_rtx (GET_MODE (dst));	  emit_move_insn (tmp, src);	  operands[1] = tmp;	}    }  return 0;}/* Function for INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET).   Define the offset between two registers, one to be eliminated, and the other   its replacement, at the start of a routine.  */intinitial_offset (from, to){  int offset = 0;  if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)    offset = UNITS_PER_WORD + frame_pointer_needed * UNITS_PER_WORD;  else    {      int regno;      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)	if (WORD_REG_USED (regno))	  offset += UNITS_PER_WORD;      /* See the comments for get_frame_size.  We need to round it up to	 STACK_BOUNDARY.  */      offset += ((get_frame_size () + STACK_BOUNDARY / BITS_PER_UNIT - 1)		 & ~(STACK_BOUNDARY / BITS_PER_UNIT - 1));      if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)	offset += UNITS_PER_WORD;	/* Skip saved PC */    }  return offset;}/* Update the condition code from the insn.  */intnotice_update_cc (body, insn)     rtx body;     rtx insn;{  switch (get_attr_cc (insn))    {    case CC_NONE:      /* Insn does not affect CC at all.  */      break;    case CC_NONE_0HIT:      /* Insn does not change CC, but the 0'th operand has been changed.  */      if (cc_status.value1 != 0	  && reg_overlap_mentioned_p (recog_operand[0], cc_status.value1))	cc_status.value1 = 0;      break;    case CC_SET_ZN:      /* Insn sets the Z,N flags of CC to recog_operand[0].	 The V flag is unusable.  The C flag may or may not be known but	 that's ok because alter_cond will change tests to use EQ/NE.  */      CC_STATUS_INIT;      cc_status.flags |= CC_OVERFLOW_UNUSABLE | CC_NO_CARRY;      cc_status.value1 = recog_operand[0];      break;    case CC_SET_ZNV:      /* Insn sets the Z,N,V flags of CC to recog_operand[0].	 The C flag may or may not be known but that's ok because	 alter_cond will change tests to use EQ/NE.  */      CC_STATUS_INIT;      cc_status.flags |= CC_NO_CARRY;      cc_status.value1 = recog_operand[0];      break;    case CC_COMPARE:      /* The insn is a compare instruction.  */      CC_STATUS_INIT;      cc_status.value1 = SET_SRC (body);      break;    case CC_CLOBBER:      /* Insn doesn't leave CC in a usable state.  */      CC_STATUS_INIT;      break;    }}/* Recognize valid operators for bit instructions */intbit_operator (x, mode)     rtx x;     enum machine_mode mode;{  enum rtx_code code = GET_CODE (x);  return (code == XOR	  || code == AND	  || code == IOR);}/* Shifts.   We devote a fair bit of code to getting efficient shifts since we can only   shift one bit at a time on the H8/300 and H8/300H and only one or two   bits at a time on the H8/S.   The basic shift methods:     * loop shifts -- emit a loop using one (or two on H8/S) bit shifts;     this is the default.  SHIFT_LOOP     * inlined shifts -- emit straight line code for the shift; this is     used when a straight line shift is about the same size or smaller     than a loop.  We allow the inline version to be slightly longer in     some cases as it saves a register.  SHIFT_INLINE     * rotate + and -- rotate the value the opposite direction, then     mask off the values we don't need.  This is used when only a few     of the bits in the original value will survive in the shifted value.     Again, this is used when it's about the same size or smaller than     a loop.  We allow this version to be slightly longer as it is usually     much faster than a loop.  SHIFT_ROT_AND     * swap (+ shifts) -- often it's possible to swap bytes/words to     simulate a shift by 8/16.  Once swapped a few inline shifts can be     added if the shift count is slightly more than 8 or 16.  This is used     when it's about the same size or smaller than a loop.  We allow this     version to be slightly longer as it is usually much faster than a loop.     SHIFT_SPECIAL     * There other oddballs.  Not worth explaining.  SHIFT_SPECIAL   Here are some thoughts on what the absolutely positively best code is.   "Best" here means some rational trade-off between code size and speed,   where speed is more preferred but not at the expense of generating 20 insns.   A trailing '*' after the shift count indicates the "best" mode isn't   implemented.      H8/300 QImode shifts   1-4    - do them inline   5-6    - ASHIFT | LSHIFTRT: rotate, mask off other bits            ASHIFTRT: loop   7      - ASHIFT | LSHIFTRT: rotate, mask off other bits            ASHIFTRT: shll, subx (propagate carry bit to all bits)   H8/300 HImode shifts   1-4    - do them inline   5-6    - loop   7      - shift 2nd half other way into carry.	    copy 1st half into 2nd half	    rotate 2nd half other way with carry	    rotate 1st half other way (no carry)	    mask off bits in 1st half (ASHIFT | LSHIFTRT).	    sign extend 1st half (ASHIFTRT)   8      - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)   9-12   - do shift by 8, inline remaining shifts   13-14* - ASHIFT | LSHIFTRT: rotate 3/2, mask, move byte, set other byte to 0          - ASHIFTRT: loop   15     - ASHIFT | LSHIFTRT: rotate 1, mask, move byte, set other byte to 0          - ASHIFTRT: shll, subx, set other byte   H8/300 SImode shifts   1-2    - do them inline   3-6    - loop   7*     - shift other way once, move bytes into place,            move carry into place (possibly with sign extension)   8      - move bytes into place, zero or sign extend other   9-14   - loop   15*    - shift other way once, move word into place, move carry into place   16     - move word, zero or sign extend other   17-23  - loop   24*    - move bytes into place, zero or sign extend other   25-27  - loop   28-30* - ASHIFT | LSHIFTRT: rotate top byte, mask, move byte into place,                               zero others            ASHIFTRT: loop   31     - ASHIFT | LSHIFTRT: rotate top byte, mask, move byte into place,                               zero others            ASHIFTRT: shll top byte, subx, copy to other bytes   H8/300H QImode shifts (same as H8/300 QImode shifts)   1-4    - do them inline   5-6    - ASHIFT | LSHIFTRT: rotate, mask off other bits            ASHIFTRT: loop   7      - ASHIFT | LSHIFTRT: rotate, mask off other bits            ASHIFTRT: shll, subx (propagate carry bit to all bits)   H8/300H HImode shifts   1-4    - do them inline   5-6    - loop   7      - shift 2nd half other way into carry.	    copy 1st half into 2nd half	    rotate entire word other way using carry	    mask off remaining bits  (ASHIFT | LSHIFTRT)	    sign extend remaining bits (ASHIFTRT)   8      - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)   9-12   - do shift by 8, inline remaining shifts   13-14  - ASHIFT | LSHIFTRT: rotate 3/2, mask, move byte, set other byte to 0          - ASHIFTRT: loop   15     - ASHIFT | LSHIFTRT: rotate 1, mask, move byte, set other byte to 0          - ASHIFTRT: shll, subx, set other byte   H8/300H SImode shifts   (These are complicated by the fact that we don't have byte level access to   the top word.)   A word is: bytes 3,2,1,0 (msb -> lsb), word 1,0 (msw -> lsw)   1-4    - do them inline   5-14   - loop   15*    - shift other way once, move word into place, move carry into place            (with sign extension for ASHIFTRT)   16     - move word into place, zero or sign extend other   17-20  - do 16bit shift, then inline remaining shifts   20-23  - loop   24*    - ASHIFT: move byte 0(msb) to byte 1, zero byte 0,                    move word 0 to word 1, zero word 0            LSHIFTRT: move word 1 to word 0, move byte 1 to byte 0,                      zero word 1, zero byte 1            ASHIFTRT: move word 1 to word 0, move byte 1 to byte 0,                      sign extend byte 0, sign extend word 0   25-27* - either loop, or            do 24 bit shift, inline rest   28-30  - ASHIFT: rotate 4/3/2, mask            LSHIFTRT: rotate 4/3/2, mask            ASHIFTRT: loop   31     - shll, subx byte 0, sign extend byte 0, sign extend word 0   H8/S QImode shifts   1-6    - do them inline   7      - ASHIFT | LSHIFTRT: rotate, mask off other bits            ASHIFTRT: shll, subx (propagate carry bit to all bits)   H8/S HImode shifts   1-7	  - do them inline   8      - move byte, zero (ASHIFT | LSHIFTRT) or sign extend other (ASHIFTRT)   9-12   - do shift by 8, inline remaining shifts   13-14  - ASHIFT | LSHIFTRT: rotate 3/2, mask, move byte, set other byte to 0          - ASHIFTRT: loop   15     - ASHIFT | LSHIFTRT: rotate 1, mask, move byte, set other byte to 0          - ASHIFTRT: shll, subx, set other byte   H8/S SImode shifts   (These are complicated by the fact that we don't have byte level access to   the top word.)   A word is: bytes 3,2,1,0 (msb -> lsb), word 1,0 (msw -> lsw)   1-10   - do them inline   11-14  - loop   15*    - shift other way once, move word into place, move carry into place            (with sign extension for ASHIFTRT)   16     - move word into place, zero or sign extend other   17-20  - do 16bit shift, then inline remaining shifts   20-23  - loop   24*    - ASHIFT: move byte 0(msb) to byte 1, zero byte 0,                    move word 0 to word 1, zero word 0            LSHIFTRT: move word 1 to word 0, move byte 1 to byte 0,                      zero word 1, zero byte 1            ASHIFTRT: move word 1 to word 0, move byte 1 to byte 0,                      sign extend byte 0, sign extend word 0   25-27* - either loop, or            do 24 bit shift, inline rest   28-30  - ASHIFT: rotate 4/3/2, mask            LSHIFTRT: rotate 4/3/2, mask            ASHIFTRT: loop   31     - shll, subx byte 0, sign extend byte 0, sign extend word 0   Panic!!!  */intnshift_operator (x, mode)     rtx x;     enum machine_mode mode;{  switch (GET_CODE (x))    {    case ASHIFTRT:    case LSHIFTRT:    case ASHIFT:      return 1;    default:      return 0;    }}/* Called from the .md file to emit code to do shifts.   Returns a boolean indicating success   (currently this is always TRUE).  */intexpand_a_shift (mode, code, operands)     enum machine_mode mode;     int code;     rtx operands[];{  emit_move_insn (operands[0], operands[1]);  /* need a loop to get all the bits we want  - we generate the     code at emit time, but need to allocate a scratch reg now  */  emit_insn (gen_rtx	     (PARALLEL, VOIDmode,	      gen_rtvec (2,			 gen_rtx (SET, VOIDmode, operands[0],				  gen_rtx (code, mode, operands[0], operands[2])),			 gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, QImode, 0)))));  return 1;}/* Shift algorithm determination.   There are various ways of doing a shift:   SHIFT_INLINE: If the amount is small enough, just generate as many one-bit                 shifts as we need.   SHIFT_ROT_AND: If the amount is large but close to either end, rotate the                  necessary bits into position and then set the rest to zero.   SHIFT_SPECIAL: Hand crafted assembler.   SHIFT_LOOP:    If the above methods fail, just loop.  */enum shift_alg{  SHIFT_INLINE,  SHIFT_ROT_AND,  SHIFT_SPECIAL,  SHIFT_LOOP,  SHIFT_MAX};/* Symbols of the various shifts which can be used as indices.  */enum shift_type  {    SHIFT_ASHIFT, SHIFT_LSHIFTRT, SHIFT_ASHIFTRT  };/* Symbols of the various modes which can be used as indices.  */enum shift_mode  {    QIshift, HIshift, SIshift  };/* For single bit shift insns, record assembler and what bits of the   condition code are valid afterwards (represented as various CC_FOO   bits, 0 means CC isn't left in a usable state).  */struct shift_insn{  char *assembler;  int cc_valid;};/* Assembler instruction shift table.   These tables are used to look up the basic shifts.   They are indexed by cpu, shift_type, and mode.*/static const struct shift_insn shift_one[2][3][3] ={/* H8/300 */  {/* SHIFT_ASHIFT */    {      { "shll\t%X0", CC_NO_CARRY },      { "add.w\t%T0,%T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },      { "add.w\t%f0,%f0\n\taddx\t%y0,%y0\n\taddx\t%z0,%z0", 0 }    },/* SHIFT_LSHIFTRT */    {      { "shlr\t%X0", CC_NO_CARRY },      { "shlr\t%t0\n\trotxr\t%s0", 0 },      { "shlr\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", 0 }    },/* SHIFT_ASHIFTRT */    {      { "shar\t%X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },      { "shar\t%t0\n\trotxr\t%s0", 0 },      { "shar\t%z0\n\trotxr\t%y0\n\trotxr\t%x0\n\trotxr\t%w0", 0 }    }  },/* H8/300H */  {/* SHIFT_ASHIFT */    {      { "shll.b\t%X0", CC_NO_CARRY },      { "shll.w\t%T0", CC_NO_CARRY },      { "shll.l\t%S0", CC_NO_CARRY }    },/* SHIFT_LSHIFTRT */    {      { "shlr.b\t%X0", CC_NO_CARRY },      { "shlr.w\t%T0", CC_NO_CARRY },      { "shlr.l\t%S0", CC_NO_CARRY }    },/* SHIFT_ASHIFTRT */    {      { "shar.b\t%X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },      { "shar.w\t%T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },      { "shar.l\t%S0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY }    }  }};static const struct shift_insn shift_two[3][3] ={/* SHIFT_ASHIFT */    {      { "shll.b\t#2,%X0", CC_NO_CARRY },      { "shll.w\t#2,%T0", CC_NO_CARRY },      { "shll.l\t#2,%S0", CC_NO_CARRY }    },/* SHIFT_LSHIFTRT */    {      { "shlr.b\t#2,%X0", CC_NO_CARRY },      { "shlr.w\t#2,%T0", CC_NO_CARRY },      { "shlr.l\t#2,%S0", CC_NO_CARRY }    },/* SHIFT_ASHIFTRT */    {      { "shar.b\t#2,%X0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },      { "shar.w\t#2,%T0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },      { "shar.l\t#2,%S0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY }    }};/* Rotates are organized by which shift they'll be used in implementing.   There's no need to record whether the cc is valid afterwards because   it is the AND insn that will decide this.  */static const char *const rotate_one[2][3][3] ={/* H8/300 */  {/* SHIFT_ASHIFT */    {      "rotr\t%X0",      "shlr\t%t0\n\trotxr\t%s0\n\tbst\t#7,%t0",      0    },/* SHIFT_LSHIFTRT */    {      "rotl\t%X0",      "shll\t%s0\n\trotxl\t%t0\n\tbst\t#0,%s0",

⌨️ 快捷键说明

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