📄 dsp16xx.c
字号:
current_frame_info.var_size = var_size; current_frame_info.args_size = args_size; current_frame_info.extra_size = extra_size; current_frame_info.reg_size = reg_size; current_frame_info.initialized = reload_completed; current_frame_info.reg_size = reg_size / UNITS_PER_WORD; current_frame_info.function_makes_calls = dsp16xx_makes_calls (); if (reg_size) { unsigned long offset = args_size + var_size + reg_size; current_frame_info.sp_save_offset = offset; current_frame_info.fp_save_offset = offset - total_size; } return total_size;}intdsp16xx_call_saved_register (regno)int regno;{ return (regs_ever_live[regno] && !call_used_regs[regno] && !IS_YBASE_REGISTER_WINDOW(regno));}intybase_regs_ever_used (){ int regno; int live = 0; for (regno = REG_YBASE0; regno <= REG_YBASE31; regno++) if (regs_ever_live[regno]) { live = 1; break; } return live;}void function_prologue (file, size)FILE *file;int size;{ int regno; long total_size; fp = reg_names[FRAME_POINTER_REGNUM]; sp = reg_names[STACK_POINTER_REGNUM]; rr = reg_names[RETURN_ADDRESS_REGNUM]; /* return address register */ a1h = reg_names[REG_A1]; total_size = compute_frame_size (size); fprintf( file, "\t/* FUNCTION PROLOGUE: */\n" ); fprintf (file, "\t/* total=%d, vars= %d, regs= %d, args=%d, extra= %d */\n", current_frame_info.total_size, current_frame_info.var_size, current_frame_info.reg_size, current_function_outgoing_args_size, current_frame_info.extra_size); fprintf (file, "\t/* fp save offset= %d, sp save_offset= %d */\n\n", current_frame_info.fp_save_offset, current_frame_info.sp_save_offset); /* Set up the 'ybase' register window. */ if (ybase_regs_ever_used()) { fprintf (file, "\t%s=%s\n", a1h, reg_names[REG_YBASE]); if (TARGET_YBASE_HIGH) fprintf (file, "\t%s=%sh-32\n", reg_names[REG_A1], a1h); else fprintf (file, "\t%s=%sh+32\n", reg_names[REG_A1], a1h); fprintf (file, "\t%s=%s\n", reg_names[REG_YBASE], a1h); } #if 0 if (current_frame_info.function_makes_calls) fprintf( file, "\t*%s++=%s\n", sp, rr ); /* Push return address */#endif if (current_frame_info.var_size) { if (current_frame_info.var_size == 1) fprintf (file, "\t*%s++\n", sp); else { if(SMALL_INTVAL(current_frame_info.var_size) && ((current_frame_info.var_size & 0x8000) == 0)) fprintf (file, "\t%s=%d\n\t*%s++%s\n", reg_names[REG_J], current_frame_info.var_size, sp, reg_names[REG_J]); else fatal ("Stack size > 32k"); } } /* Save any registers this function uses, unless they are * used in a call, in which case we don't need to */ for( regno = 0; regno < FIRST_PSEUDO_REGISTER; ++ regno ) if (dsp16xx_call_saved_register (regno)) {#if OLD_REGISTER_SAVE fprintf( file, "\t*%s++=%s\n", sp, reg_names[regno] );#else fprintf( file, "\tpush(*%s)=%s\n", sp, reg_names[regno] );#endif } if (current_frame_info.args_size) { if (current_frame_info.args_size == 1) fprintf (file, "\t*%s++\n", sp); else { if(SMALL_INTVAL(current_frame_info.args_size) && ((current_frame_info.args_size & 0x8000) == 0)) fprintf (file, "\t%s=%d\n\t*%s++%s\n", reg_names[REG_J], current_frame_info.args_size, sp, reg_names[REG_J]); else fatal ("Stack size > 32k"); } } if (frame_pointer_needed) { fprintf( file, "\t%s=%s\n", a1h, sp ); fprintf( file, "\t%s=%s\n", fp, a1h ); /* Establish new base frame */ fprintf( file, "\t%s=%d\n", reg_names[REG_J], -total_size); fprintf( file, "\t*%s++%s\n", fp, reg_names[REG_J]); } fprintf( file, "\t/* END FUNCTION PROLOGUE: */\n\n" );}voidinit_emulation_routines (){ dsp16xx_addhf3_libcall = (rtx) 0; dsp16xx_subhf3_libcall = (rtx) 0; dsp16xx_mulhf3_libcall = (rtx) 0; dsp16xx_divhf3_libcall = (rtx) 0; dsp16xx_cmphf3_libcall = (rtx) 0; dsp16xx_fixhfhi2_libcall = (rtx) 0; dsp16xx_floathihf2_libcall = (rtx) 0; dsp16xx_neghf2_libcall = (rtx) 0; dsp16xx_mulhi3_libcall = (rtx) 0; dsp16xx_udivqi3_libcall = (rtx) 0; dsp16xx_udivhi3_libcall = (rtx) 0; dsp16xx_divqi3_libcall = (rtx) 0; dsp16xx_divhi3_libcall = (rtx) 0; dsp16xx_modqi3_libcall = (rtx) 0; dsp16xx_modhi3_libcall = (rtx) 0; dsp16xx_umodqi3_libcall = (rtx) 0; dsp16xx_umodhi3_libcall = (rtx) 0; dsp16xx_ashrhi3_libcall = (rtx) 0; dsp16xx_ashlhi3_libcall = (rtx) 0; dsp16xx_ucmphi2_libcall = (rtx) 0; dsp16xx_lshrhi3_libcall = (rtx) 0;}voidfunction_epilogue (file, size)FILE *file;int size;{ int regno; int initial_stack_dec = 0; fp = reg_names[FRAME_POINTER_REGNUM]; sp = reg_names[STACK_POINTER_REGNUM]; rr = reg_names[RETURN_ADDRESS_REGNUM]; /* return address register */ a1h = reg_names[REG_A1]; fprintf( file, "\n\t/* FUNCTION EPILOGUE: */\n" ); if (current_frame_info.args_size) { if (current_frame_info.args_size == 1) fprintf (file, "\t*%s--\n", sp); else { fprintf (file, "\t%s=%d\n\t*%s++%s\n", reg_names[REG_J], -current_frame_info.args_size, sp, reg_names[REG_J]); } } if (ybase_regs_ever_used()) { fprintf (file, "\t%s=%s\n", a1h, reg_names[REG_YBASE]); if (TARGET_YBASE_HIGH) fprintf (file, "\t%s=%sh+32\n", reg_names[REG_A1], a1h); else fprintf (file, "\t%s=%sh-32\n", reg_names[REG_A1], a1h); fprintf (file, "\t%s=%s\n", reg_names[REG_YBASE], a1h); } for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; --regno) if (dsp16xx_call_saved_register(regno)) {#if OLD_REGISTER_SAVE if (!initial_stack_dec) { initial_stack_dec = 1; fprintf (file, "\t*%s--\n", sp); }#endif#if OLD_REGISTER_SAVE fprintf( file, "\t%s=*%s--\n", reg_names[regno], sp );#else fprintf( file, "\t%s=pop(*%s)\n", reg_names[regno], sp );#endif } /* If we restored any registers we have to account for the initial pre-decrement. But only if we had any local variables or spills. */#if OLD_REGISTER_SAVE if (initial_stack_dec) fprintf (file, "\t*%s++\n", sp);#endif if (current_frame_info.var_size) { if (current_frame_info.var_size == 1) fprintf (file, "\t*%s--\n", sp); else { fprintf (file, "\t%s=%d\n\t*%s++%s\n", reg_names[REG_J], -current_frame_info.var_size, sp, reg_names[REG_J]); } } fprintf (file, "\treturn\n"); /* Reset the frame info for the next function */ current_frame_info = zero_frame_info; init_emulation_routines ();}/* Emit insns to move operands[1] into operands[0]. Return 1 if we have written out everything that needs to be done to do the move. Otherwise, return 0 and the caller will emit the move normally. */intemit_move_sequence (operands, mode) rtx *operands; enum machine_mode mode;{ register rtx operand0 = operands[0]; register rtx operand1 = operands[1]; /* We can only store registers to memory. */ if (GET_CODE (operand0) == MEM && GET_CODE (operand1) != REG) operands[1] = force_reg (mode, operand1); return 0;}voiddouble_reg_from_memory (operands)rtx operands[];{ rtx xoperands[4]; if (GET_CODE(XEXP(operands[1],0)) == POST_INC) { output_asm_insn ("%u0=%1", operands); output_asm_insn ("%w0=%1", operands); } else if (GET_CODE(XEXP(operands[1],0)) == POST_DEC) { xoperands[1] = XEXP (XEXP (operands[1], 0), 0); xoperands[0] = operands[0]; /* We can't use j anymore since the compiler can allocate it. *//* output_asm_insn ("j=-3\n\t%u0=*%1++\n\t%w0=*%1++j", xoperands); */ output_asm_insn ("%u0=*%1++\n\t%w0=*%1--\n\t*%1--\n\t*%1--", xoperands); } else if (GET_CODE(XEXP(operands[1],0)) == PLUS) { rtx addr; rtx base; int offset; output_asm_insn ("%u0=%1", operands); /* In order to print out the least significant word we must use 'offset + 1'. */ addr = XEXP (operands[1], 0); if (GET_CODE (XEXP(addr,0)) == CONST_INT) offset = INTVAL(XEXP(addr,0)) + 1; else if (GET_CODE (XEXP(addr,1)) == CONST_INT) offset = INTVAL(XEXP(addr,1)) + 1; fprintf (asm_out_file, "\t%s=*(%d)\n", reg_names[REGNO(operands[0]) + 1], offset + 31); } else { xoperands[1] = XEXP(operands[1],0); xoperands[0] = operands[0]; output_asm_insn ("%u0=*%1++\n\t%w0=*%1--", xoperands); }}voiddouble_reg_to_memory (operands)rtx operands[];{ rtx xoperands[4]; if (GET_CODE(XEXP(operands[0],0)) == POST_INC) { output_asm_insn ("%0=%u1", operands); output_asm_insn ("%0=%w1", operands); } else if (GET_CODE(XEXP(operands[0],0)) == POST_DEC) { xoperands[0] = XEXP (XEXP (operands[0], 0), 0); xoperands[1] = operands[1]; /* We can't use j anymore since the compiler can allocate it. *//* output_asm_insn ("j=-3\n\t*%0++=%u1\n\t*%0++j=%w1", xoperands); */ output_asm_insn ("*%0++=%u1\n\t*%0--=%w1\n\t*%0--\n\t*%0--", xoperands); } else if (GET_CODE(XEXP(operands[0],0)) == PLUS) { rtx addr; int offset; output_asm_insn ("%0=%u1", operands); /* In order to print out the least significant word we must use 'offset + 1'. */ addr = XEXP (operands[0], 0); if (GET_CODE (XEXP(addr,0)) == CONST_INT) offset = INTVAL(XEXP(addr,0)) + 1; else if (GET_CODE (XEXP(addr,1)) == CONST_INT) offset = INTVAL(XEXP(addr,1)) + 1; else fatal ("Invalid addressing mode"); fprintf (asm_out_file, "\t*(%d)=%s\n", offset + 31, reg_names[REGNO(operands[1]) + 1]); } else { xoperands[0] = XEXP(operands[0],0); xoperands[1] = operands[1]; output_asm_insn ("*%0++=%u1\n\t*%0--=%w1", xoperands); }}voidoverride_options (){ if (chip_name == (char *) 0) chip_name = DEFAULT_CHIP_NAME; if (text_seg_name == (char *) 0) text_seg_name = DEFAULT_TEXT_SEG_NAME; if (data_seg_name == (char *) 0) data_seg_name = DEFAULT_DATA_SEG_NAME; if (bss_seg_name == (char *) 0) bss_seg_name = DEFAULT_BSS_SEG_NAME; if (const_seg_name == (char *) 0) const_seg_name = DEFAULT_CONST_SEG_NAME; save_chip_name = (char *) xmalloc (strlen(chip_name) + 1); strcpy (save_chip_name, chip_name); rsect_text = (char *) xmalloc (strlen(".rsect ") + strlen(text_seg_name) + 3); rsect_data = (char *) xmalloc (strlen(".rsect ") + strlen(data_seg_name) + 3); rsect_bss = (char *) xmalloc (strlen(".rsect ") + strlen(bss_seg_name) + 3); rsect_const = (char *) xmalloc (strlen(".rsect ") + strlen(const_seg_name) + 3); sprintf (rsect_text, ".rsect \"%s\"", text_seg_name); sprintf (rsect_data, ".rsect \"%s\"", data_seg_name); sprintf (rsect_bss, ".rsect \"%s\"", bss_seg_name); sprintf (rsect_const, ".rsect \"%s\"", const_seg_name); if (optimize) { if (TARGET_OPTIMIZE_SPEED) { flag_unroll_loops = 1; flag_inline_functions = 1; } }}enum rtx_codenext_cc_user_code (insn)rtx insn;{ if ( !(insn = next_cc0_user (insn))) abort (); else if (GET_CODE (insn) == JUMP_INSN && GET_CODE (PATTERN (insn)) == SET && GET_CODE (SET_SRC (PATTERN (insn))) == IF_THEN_ELSE) return GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)); else if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SET && comparison_operator (SET_SRC (PATTERN (insn)), VOIDmode)) return GET_CODE (SET_SRC (PATTERN (insn))); else abort ();}intnext_cc_user_unsigned (insn) rtx insn;{ switch (next_cc_user_code (insn)) { case GTU: case GEU: case LTU: case LEU: return 1; default: return 0; }}voidprint_operand(file, op, letter)FILE *file;rtx op;int letter;{ enum rtx_code code; code = GET_CODE(op); switch (letter) { case 'I': code = reverse_condition (code); /* Fallthrough */ case 'C': if (code == EQ) { fputs ("eq", file); return; } else if (code == NE) { fputs ("ne", file); return; } else if (code == GT || code == GTU) { fputs ("gt", file); return; } else if (code == LT || code == LTU) { fputs ("mi", file); return; } else if (code == GE || code == GEU) { fputs ("pl", file); return; } else if (code == LE || code == LEU) { fputs ("le", file); return; } else abort (); break; default: break; } if( code == REG ) { /* Print the low half of a 32-bit register pair */ if (letter == 'w') fprintf( file, "%s", reg_names[REGNO(op)+1] ); else if (letter == 'u' || !letter) fprintf( file, "%s", reg_names[REGNO(op)]); else if (letter == 'b') fprintf ( file, "%sh", reg_names[REGNO(op)]); else if (letter == 'm') fprintf (file, "%s", himode_reg_name[REGNO(op)]); else fatal("Bad register extension code"); } else if( code == MEM ) output_address( XEXP(op,0) ); else if( code == CONST_INT ) { HOST_WIDE_INT val = INTVAL (op); if( letter == 'H' ) fprintf( file, HOST_WIDE_INT_PRINT_HEX, val & 0xffff); else if (letter == 'h') fprintf( file, HOST_WIDE_INT_PRINT_DEC, val); else if( letter == 'U' ) fprintf( file, HOST_WIDE_INT_PRINT_HEX, (val >> 16) & 0xffff); else output_addr_const( file, op ); } else if( code == CONST_DOUBLE && GET_MODE(op) != DImode ) { union { double d; int i[2]; } u; union { float f; int i; } u1; u.i[0] = CONST_DOUBLE_LOW (op); u.i[1] = CONST_DOUBLE_HIGH (op); u1.f = u.d; fprintf( file, "0x%x", u1.i ); } else output_addr_const( file, op);}voidprint_operand_address(file, addr)FILE *file;rtx addr;{ rtx base; int offset; switch (GET_CODE (addr)) { case REG: fprintf (file, "*%s", reg_names[REGNO (addr)]); break; case POST_DEC: fprintf (file, "*%s--", reg_names[REGNO (XEXP (addr, 0))]); break; case POST_INC: fprintf (file, "*%s++", reg_names[REGNO (XEXP (addr, 0))]); break; case PLUS: if (GET_CODE (XEXP(addr,0)) == CONST_INT) offset = INTVAL(XEXP(addr,0)), base = XEXP(addr,1); else if (GET_CODE (XEXP(addr,1)) == CONST_INT)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -