📄 h8300.c
字号:
intbit_operand (op, mode) rtx op; enum machine_mode mode;{ /* We can except any general operand, expept that MEM operands must be limited to those that use addresses valid for the 'U' constraint. */ if (!general_operand (op, mode)) return 0; /* Accept any mem during RTL generation. Otherwise, the code that does insv and extzv will think that we can not handle memory. However, to avoid reload problems, we only accept 'U' MEM operands after RTL generation. This means that any named pattern which uses this predicate must force its operands to match 'U' before emitting RTL. */ if (GET_CODE (op) == REG) return 1; if (GET_CODE (op) == SUBREG) return 1; if (!rtx_equal_function_value_matters) /* We're building rtl. */ return GET_CODE (op) == MEM; else return (GET_CODE (op) == MEM && EXTRA_CONSTRAINT (op, 'U'));}intbit_memory_operand (op, mode) rtx op; enum machine_mode mode ATTRIBUTE_UNUSED;{ return (GET_CODE (op) == MEM && EXTRA_CONSTRAINT (op, 'U'));}/* Handle machine specific pragmas for compatibility with existing compilers for the H8/300. pragma saveall generates prolog/epilog code which saves and restores all the registers on function entry. pragma interrupt saves and restores all registers, and exits with an rte instruction rather than an rts. A pointer to a function with this attribute may be safely used in an interrupt vector. */voidh8300_pr_interrupt (pfile) cpp_reader *pfile ATTRIBUTE_UNUSED;{ interrupt_handler = 1;}voidh8300_pr_saveall (pfile) cpp_reader *pfile ATTRIBUTE_UNUSED;{ pragma_saveall = 1;}/* If the next function argument with MODE and TYPE is to be passed in a register, return a reg RTX for the hard register in which to pass the argument. CUM represents the state after the last argument. If the argument is to be pushed, NULL_RTX is returned. */rtxfunction_arg (cum, mode, type, named) CUMULATIVE_ARGS *cum; enum machine_mode mode; tree type; int named;{ static const char *const hand_list[] = { "__main", "__cmpsi2", "__divhi3", "__modhi3", "__udivhi3", "__umodhi3", "__divsi3", "__modsi3", "__udivsi3", "__umodsi3", "__mulhi3", "__mulsi3", "__reg_memcpy", "__reg_memset", "__ucmpsi2", 0, }; rtx result = NULL_RTX; const char *fname; int regpass = 0; /* Never pass unnamed arguments in registers. */ if (!named) return NULL_RTX; /* Pass 3 regs worth of data in regs when user asked on the command line. */ if (TARGET_QUICKCALL) regpass = 3; /* If calling hand written assembler, use 4 regs of args. */ if (cum->libcall) { const char * const *p; fname = XSTR (cum->libcall, 0); /* See if this libcall is one of the hand coded ones. */ for (p = hand_list; *p && strcmp (*p, fname) != 0; p++) ; if (*p) regpass = 4; } if (regpass) { int size; if (mode == BLKmode) size = int_size_in_bytes (type); else size = GET_MODE_SIZE (mode); if (size + cum->nbytes <= regpass * UNITS_PER_WORD && cum->nbytes / UNITS_PER_WORD <= 3) result = gen_rtx_REG (mode, cum->nbytes / UNITS_PER_WORD); } return result;}/* Return the cost of the rtx R with code CODE. */intconst_costs (r, c, outer_code) rtx r; enum rtx_code c; enum rtx_code outer_code;{ switch (c) { case CONST_INT: switch (INTVAL (r)) { case 0: return 0; case 1: case 2: case -1: case -2: return 0 + (outer_code == SET); case 4: case -4: if (TARGET_H8300H || TARGET_H8300S) return 0 + (outer_code == SET); else return 1; default: return 1; } case CONST: case LABEL_REF: case SYMBOL_REF: return 3; case CONST_DOUBLE: return 20; default: return 4; }}inth8300_and_costs (x) rtx x;{ rtx operands[4]; if (GET_MODE (x) == QImode) return 1; if (GET_MODE (x) != HImode && GET_MODE (x) != SImode) return 100; operands[0] = NULL; operands[1] = NULL; operands[2] = XEXP (x, 1); operands[3] = x; return compute_logical_op_length (GET_MODE (x), operands);}inth8300_shift_costs (x) rtx x;{ rtx operands[4]; if (GET_MODE (x) != QImode && GET_MODE (x) != HImode && GET_MODE (x) != SImode) return 100; operands[0] = NULL; operands[1] = NULL; operands[2] = XEXP (x, 1); operands[3] = x; return compute_a_shift_length (NULL, operands);}/* Documentation for the machine specific operand escapes: 'E' like s but negative. 'F' like t but negative. 'G' constant just the negative 'R' print operand as a byte:8 address if appropriate, else fall back to 'X' handling. 'S' print operand as a long word 'T' print operand as a word 'V' find the set bit, and print its number. 'W' find the clear bit, and print its number. 'X' print operand as a byte 'Y' print either l or h depending on whether last 'Z' operand < 8 or >= 8. If this operand isn't a register, fall back to 'R' handling. 'Z' print int & 7. 'b' print the bit opcode 'e' first word of 32 bit value - if reg, then least reg. if mem then least. if const then most sig word 'f' second word of 32 bit value - if reg, then biggest reg. if mem then +2. if const then least sig word 'j' print operand as condition code. 'k' print operand as reverse condition code. 's' print as low byte of 16 bit value 't' print as high byte of 16 bit value 'w' print as low byte of 32 bit value 'x' print as 2nd byte of 32 bit value 'y' print as 3rd byte of 32 bit value 'z' print as msb of 32 bit value*//* Return assembly language string which identifies a comparison type. */static const char *cond_string (code) enum rtx_code code;{ switch (code) { case NE: return "ne"; case EQ: return "eq"; case GE: return "ge"; case GT: return "gt"; case LE: return "le"; case LT: return "lt"; case GEU: return "hs"; case GTU: return "hi"; case LEU: return "ls"; case LTU: return "lo"; default: abort (); }}/* Print operand X using operand code CODE to assembly language output file FILE. */voidprint_operand (file, x, code) FILE *file; rtx x; int code;{ /* This is used for communication between codes V,W,Z and Y. */ static int bitint; switch (code) { case 'E': switch (GET_CODE (x)) { case REG: fprintf (file, "%sl", names_big[REGNO (x)]); break; case CONST_INT: fprintf (file, "#%d", (-INTVAL (x)) & 0xff); break; default: abort (); } break; case 'F': switch (GET_CODE (x)) { case REG: fprintf (file, "%sh", names_big[REGNO (x)]); break; case CONST_INT: fprintf (file, "#%d", ((-INTVAL (x)) & 0xff00) >> 8); break; default: abort (); } break; case 'G': if (GET_CODE (x) != CONST_INT) abort (); fprintf (file, "#%d", 0xff & (-INTVAL (x))); break; case 'S': if (GET_CODE (x) == REG) fprintf (file, "%s", names_extended[REGNO (x)]); else goto def; break; case 'T': if (GET_CODE (x) == REG) fprintf (file, "%s", names_big[REGNO (x)]); else goto def; break; case 'V': bitint = exact_log2 (INTVAL (x) & 0xff); if (bitint == -1) abort (); fprintf (file, "#%d", bitint); break; case 'W': bitint = exact_log2 ((~INTVAL (x)) & 0xff); if (bitint == -1) abort (); fprintf (file, "#%d", bitint); break; case 'R': case 'X': if (GET_CODE (x) == REG) fprintf (file, "%s", byte_reg (x, 0)); else goto def; break; case 'Y': if (bitint == -1) abort (); if (GET_CODE (x) == REG) fprintf (file, "%s%c", names_big[REGNO (x)], bitint > 7 ? 'h' : 'l'); else print_operand (file, x, 'R'); bitint = -1; break; case 'Z': bitint = INTVAL (x); fprintf (file, "#%d", bitint & 7); break; case 'b': switch (GET_CODE (x)) { case IOR: fprintf (file, "bor"); break; case XOR: fprintf (file, "bxor"); break; case AND: fprintf (file, "band"); break; default: break; } break; case 'e': switch (GET_CODE (x)) { case REG: if (TARGET_H8300) fprintf (file, "%s", names_big[REGNO (x)]); else fprintf (file, "%s", names_upper_extended[REGNO (x)]); break; case MEM: print_operand (file, x, 0); break; case CONST_INT: fprintf (file, "#%d", ((INTVAL (x) >> 16) & 0xffff)); break; case CONST_DOUBLE: { long val; REAL_VALUE_TYPE rv; REAL_VALUE_FROM_CONST_DOUBLE (rv, x); REAL_VALUE_TO_TARGET_SINGLE (rv, val); fprintf (file, "#%ld", ((val >> 16) & 0xffff)); break; } default: abort (); break; } break; case 'f': switch (GET_CODE (x)) { case REG: if (TARGET_H8300) fprintf (file, "%s", names_big[REGNO (x) + 1]); else fprintf (file, "%s", names_big[REGNO (x)]); break; case MEM: x = adjust_address (x, HImode, 2); print_operand (file, x, 0); break; case CONST_INT: fprintf (file, "#%d", INTVAL (x) & 0xffff); break; case CONST_DOUBLE: { long val; REAL_VALUE_TYPE rv; REAL_VALUE_FROM_CONST_DOUBLE (rv, x); REAL_VALUE_TO_TARGET_SINGLE (rv, val); fprintf (file, "#%ld", (val & 0xffff)); break; } default: abort (); } break; case 'j': fputs (cond_string (GET_CODE (x)), file); break; case 'k': fputs (cond_string (reverse_condition (GET_CODE (x))), file); break; case 's': if (GET_CODE (x) == CONST_INT) fprintf (file, "#%d", (INTVAL (x)) & 0xff); else fprintf (file, "%s", byte_reg (x, 0)); break; case 't': if (GET_CODE (x) == CONST_INT) fprintf (file, "#%d", (INTVAL (x) >> 8) & 0xff); else fprintf (file, "%s", byte_reg (x, 1)); break; case 'u': if (GET_CODE (x) != CONST_INT) abort (); fprintf (file, "%d", INTVAL (x)); break; case 'w': if (GET_CODE (x) == CONST_INT) fprintf (file, "#%d", INTVAL (x) & 0xff); else fprintf (file, "%s", byte_reg (x, TARGET_H8300 ? 2 : 0)); break; case 'x': if (GET_CODE (x) == CONST_INT) fprintf (file, "#%d", (INTVAL (x) >> 8) & 0xff); else fprintf (file, "%s", byte_reg (x, TARGET_H8300 ? 3 : 1)); break; case 'y': if (GET_CODE (x) == CONST_INT) fprintf (file, "#%d", (INTVAL (x) >> 16) & 0xff); else fprintf (file, "%s", byte_reg (x, 0)); break; case 'z': if (GET_CODE (x) == CONST_INT) fprintf (file, "#%d", (INTVAL (x) >> 24) & 0xff); else fprintf (file, "%s", byte_reg (x, 1)); break; default: def: switch (GET_CODE (x)) { case REG: switch (GET_MODE (x)) { case QImode:#if 0 /* Is it asm ("mov.b %0,r2l", ...) */ fprintf (file, "%s", byte_reg (x, 0));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -