📄 convex.c
字号:
prev_store = prev_store_2 = 0; while (len > 0) { if (len >= 8 && maxsize >= 8) mode = DImode; else if (len >= 4 && maxsize >= 4) mode = SImode; else if (len >= 2 && maxsize >= 2) mode = HImode; else mode = QImode; /* If no temp pseudo to reuse, or not the right mode, make one */ if (! reg || GET_MODE (reg) != mode) reg = gen_reg_rtx (mode); /* Get src and dest in the right mode */ if (GET_MODE (src) != mode) src = change_address (src, mode, 0), dest = change_address (dest, mode, 0); /* Make load and store patterns for this piece */ load = gen_rtx (SET, VOIDmode, reg, src); store = gen_rtx (SET, VOIDmode, dest, reg); /* Emit the load and the store from last time. When we emit a store, we can reuse its temp reg. */ emit_insn (load); if (prev_store) { reg = SET_SRC (prev_store); emit_insn (prev_store); } else reg = 0; /* Queue up the store, for next time or the time after that. */ if (nregs == 2) prev_store = store; else prev_store = prev_store_2, prev_store_2 = store; /* Advance to next piece. */ size = GET_MODE_SIZE (mode); src = adj_offsettable_operand (src, size); dest = adj_offsettable_operand (dest, size); len -= size; } /* Finally, emit the last stores. */ if (prev_store) emit_insn (prev_store); if (prev_store_2) emit_insn (prev_store_2);}static voidexpand_movstr_call (operands) rtx *operands;{ emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "memcpy"), 0, VOIDmode, 3, XEXP (operands[0], 0), Pmode, XEXP (operands[1], 0), Pmode, convert_to_mode (TYPE_MODE (sizetype), operands[2], TREE_UNSIGNED (sizetype)), TYPE_MODE (sizetype));}#if _IEEE_FLOAT_#define MAX_FLOAT 3.4028234663852886e+38#define MIN_FLOAT 1.1754943508222875e-38#else#define MAX_FLOAT 1.7014117331926443e+38#define MIN_FLOAT 2.9387358770557188e-39#endifintcheck_float_value (mode, dp, overflow) enum machine_mode mode; REAL_VALUE_TYPE *dp; int overflow;{ REAL_VALUE_TYPE d = *dp; if (overflow) { *dp = MAX_FLOAT; return 1; } if (mode == SFmode) { if (d > MAX_FLOAT) { *dp = MAX_FLOAT; return 1; } else if (d < -MAX_FLOAT) { *dp = -MAX_FLOAT; return 1; } else if ((d > 0 && d < MIN_FLOAT) || (d < 0 && d > -MIN_FLOAT)) { *dp = 0.0; return 1; } } return 0;}/* Output the label at the start of a function. Precede it with the number of formal args so debuggers will have some idea of how many args to print. */voidasm_declare_function_name (file, name, decl) FILE *file; char *name; tree decl;{ tree parms; int nargs = list_length (DECL_ARGUMENTS (decl)); char *p, c; extern char *version_string; static char vers[4]; int i; p = version_string; for (i = 0; i < 3; ) { c = *p; if (c - '0' < (unsigned) 10) vers[i++] = c; if (c == 0 || c == ' ') vers[i++] = '0'; else p++; } fprintf (file, "\tds.b \"g%s\"\n", vers); if (nargs < 100) fprintf (file, "\tds.b \"+%02d\\0\"\n", nargs); else fprintf (file, "\tds.b \"+00\\0\"\n"); ASM_OUTPUT_LABEL (file, name);}/* Print an instruction operand X on file FILE. CODE is the code from the %-spec that requested printing this operand; if `%z3' was used to print operand 3, then CODE is 'z'. *//* Convex codes: %u prints a CONST_DOUBLE's high word %v prints a CONST_DOUBLE's low word %z prints a CONST_INT shift count as a multiply operand -- viz. 1 << n. */print_operand (file, x, code) FILE *file; rtx x; char code;{ long u[2]; REAL_VALUE_TYPE d; switch (GET_CODE (x)) { case REG: fprintf (file, "%s", reg_names[REGNO (x)]); break; case MEM: output_address (XEXP (x, 0)); break; case CONST_DOUBLE: REAL_VALUE_FROM_CONST_DOUBLE (d, x); switch (GET_MODE (x)) { case DFmode:#if 0 /* doesn't work, produces dfloats */ REAL_VALUE_TO_TARGET_DOUBLE (d, u); #else { union { double d; int i[2]; } t; t.d = d; u[0] = t.i[0]; u[1] = t.i[1]; }#endif if (code == 'u') fprintf (file, "#%#x", u[0]); else if (code == 'v') fprintf (file, "#%#x", u[1]); else outfloat (file, d, "%.17e", "#", ""); break; case SFmode: outfloat (file, d, "%.9e", "#", ""); break; default: if (code == 'u') fprintf (file, "#%d", CONST_DOUBLE_HIGH (x)); else fprintf (file, "#%d", CONST_DOUBLE_LOW (x)); } break; default: if (code == 'z') { if (GET_CODE (x) != CONST_INT) abort (); fprintf (file, "#%d", 1 << INTVAL (x)); } else { putc ('#', file); output_addr_const (file, x); } }}/* Print a memory operand whose address is X, on file FILE. */print_operand_address (file, addr) FILE *file; rtx addr;{ rtx index = 0; rtx offset = 0; if (GET_CODE (addr) == MEM) { fprintf (file, "@"); addr = XEXP (addr, 0); } switch (GET_CODE (addr)) { case REG: index = addr; break; case PLUS: index = XEXP (addr, 0); if (REG_P (index)) offset = XEXP (addr, 1); else { offset = XEXP (addr, 0); index = XEXP (addr, 1); if (! REG_P (index)) abort (); } break; default: offset = addr; break; } if (offset) output_addr_const (file, offset); if (index) fprintf (file, "(%s)", reg_names[REGNO (index)]);}/* Output a float to FILE, value VALUE, format FMT, preceded by PFX and followed by SFX. */outfloat (file, value, fmt, pfx, sfx) FILE *file; REAL_VALUE_TYPE value; char *fmt, *pfx, *sfx;{ char buf[64]; fputs (pfx, file); REAL_VALUE_TO_DECIMAL (value, fmt, buf); fputs (buf, file); fputs (sfx, file);}/* Here during RTL generation of return. If we are at the final return in a function, go through the function and replace pushes with stores into a frame arg block. This is similar to what ACCUMULATE_OUTGOING_ARGS does, but we must index off the frame pointer, not the stack pointer, and the calling sequence does not require the arg block to be at the top of the stack. */replace_arg_pushes (){ /* Doesn't work yet. */}/* Output the insns needed to do a call. operands[] are 0 - MEM, the place to call 1 - CONST_INT, the number of bytes in the arg list 2 - CONST_INT, the number of arguments 3 - CONST_INT, the number of bytes to pop 4 - address of the arg list. */char *output_call (insn, operands) rtx insn, *operands;{ if (operands[4] == stack_pointer_rtx) output_asm_insn ("mov sp,ap", operands); else abort (); if (TARGET_ARGCOUNT) output_asm_insn ("pshea %a2", operands); output_asm_insn ("calls %0", operands); output_asm_insn ("ld.w 12(fp),ap", operands); if (operands[4] == stack_pointer_rtx && operands[3] != const0_rtx) output_asm_insn ("add.w %3,sp", operands); return "";}/* Here after reloading, before the second scheduling pass. */emit_ap_optimizations (){ /* Removed for now. */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -