📄 i960.md
字号:
&& rtx_equal_function_value_matters == 0) && (register_operand (operands[0], TImode) || register_operand (operands[1], TImode) || operands[1] == const0_rtx)" "*{ switch (which_alternative) { case 0: case 1: case 3: case 4: return i960_output_move_quad (operands[0], operands[1]); case 2: return i960_output_ldconst (operands[0], operands[1]); case 5: return i960_output_move_quad_zero (operands[0]); default: abort(); }}" [(set_attr "type" "move,move,load,load,store,store")]);; The store case can not be separate. See comment above.(define_insn "" [(set (match_operand:TI 0 "general_operand" "=d,d,d,d,m") (match_operand:TI 1 "general_operand" "d,I,i,m,d"))] "(current_function_args_size != 0 || current_function_stdarg != 0 || rtx_equal_function_value_matters != 0) && (register_operand (operands[0], TImode) || register_operand (operands[1], TImode))" "*{ switch (which_alternative) { case 0: case 1: case 3: case 4: return i960_output_move_quad (operands[0], operands[1]); case 2: return i960_output_ldconst (operands[0], operands[1]); default: abort(); }}" [(set_attr "type" "move,move,load,load,store")])(define_insn "*store_unaligned_ti_reg" [(set (match_operand:TI 0 "general_operand" "=d,m") (match_operand:TI 1 "register_operand" "d,d")) (clobber (match_scratch:SI 2 "=X,&d"))] "" "*{ if (which_alternative == 0) return i960_output_move_quad (operands[0], operands[1]); operands[3] = gen_rtx_MEM (word_mode, operands[2]); operands[4] = adjust_address (operands[3], word_mode, UNITS_PER_WORD); operands[5] = adjust_address (operands[4], word_mode, UNITS_PER_WORD); operands[6] = adjust_address (operands[5], word_mode, UNITS_PER_WORD); return \"lda %0,%2\;st %1,%3\;st %D1,%4\;st %E1,%5\;st %F1,%6\";}" [(set_attr "type" "move,store")])(define_expand "store_multiple" [(set (match_operand:SI 0 "" "") ;;- dest (match_operand:SI 1 "" "")) ;;- src (use (match_operand:SI 2 "" ""))] ;;- nregs "" "{ int regno; int count; int offset = 0; if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != REG || GET_CODE (operands[2]) != CONST_INT) FAIL; count = INTVAL (operands[2]); if (count > 12) FAIL; regno = REGNO (operands[1]); while (count >= 4 && ((regno & 3) == 0)) { emit_move_insn (adjust_address (operands[0], TImode, offset), gen_rtx_REG (TImode, regno)); count -= 4; regno += 4; offset += 16; } while (count >= 2 && ((regno & 1) == 0)) { emit_move_insn (adjust_address (operands[0], DImode, offset), gen_rtx_REG (DImode, regno)); count -= 2; regno += 2; offset += 8; } while (count > 0) { emit_move_insn (adjust_address (operands[0], SImode, offset), gen_rtx_REG (SImode, regno)); count -= 1; regno += 1; offset += 4; } DONE;}");; Floating point move insns(define_expand "movdf" [(set (match_operand:DF 0 "general_operand" "") (match_operand:DF 1 "fpmove_src_operand" ""))] "" "{ if (emit_move_sequence (operands, DFmode)) DONE;}")(define_insn "" [(set (match_operand:DF 0 "general_operand" "=r,*f,d,d,m,o") (match_operand:DF 1 "fpmove_src_operand" "r,GH,F,m,d,G"))] "(current_function_args_size == 0 && current_function_stdarg == 0 && rtx_equal_function_value_matters == 0) && (register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode) || operands[1] == CONST0_RTX (DFmode))" "*{ switch (which_alternative) { case 0: if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) return \"movrl %1,%0\"; else return \"movl %1,%0\"; case 1: return \"movrl %1,%0\"; case 2: return i960_output_ldconst (operands[0], operands[1]); case 3: return \"ldl %1,%0\"; case 4: return \"stl %1,%0\"; case 5: operands[1] = adjust_address (operands[0], VOIDmode, 4); return \"st g14,%0\;st g14,%1\"; default: abort(); }}" [(set_attr "type" "move,move,load,fpload,fpstore,fpstore")])(define_insn "" [(set (match_operand:DF 0 "general_operand" "=r,*f,d,d,m") (match_operand:DF 1 "fpmove_src_operand" "r,GH,F,m,d"))] "(current_function_args_size != 0 || current_function_stdarg != 0 || rtx_equal_function_value_matters != 0) && (register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode))" "*{ switch (which_alternative) { case 0: if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) return \"movrl %1,%0\"; else return \"movl %1,%0\"; case 1: return \"movrl %1,%0\"; case 2: return i960_output_ldconst (operands[0], operands[1]); case 3: return \"ldl %1,%0\"; case 4: return \"stl %1,%0\"; default: abort(); }}" [(set_attr "type" "move,move,load,fpload,fpstore")])(define_expand "movsf" [(set (match_operand:SF 0 "general_operand" "") (match_operand:SF 1 "fpmove_src_operand" ""))] "" "{ if (emit_move_sequence (operands, SFmode)) DONE;}")(define_insn "" [(set (match_operand:SF 0 "general_operand" "=r,*f,d,d,m") (match_operand:SF 1 "fpmove_src_operand" "r,GH,F,m,dG"))] "(current_function_args_size == 0 && current_function_stdarg == 0 && rtx_equal_function_value_matters == 0) && (register_operand (operands[0], SFmode) || register_operand (operands[1], SFmode) || operands[1] == CONST0_RTX (SFmode))" "*{ switch (which_alternative) { case 0: if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) return \"movr %1,%0\"; else return \"mov %1,%0\"; case 1: return \"movr %1,%0\"; case 2: return i960_output_ldconst (operands[0], operands[1]); case 3: return \"ld %1,%0\"; case 4: if (operands[1] == CONST0_RTX (SFmode)) return \"st g14,%0\"; return \"st %1,%0\"; default: abort(); }}" [(set_attr "type" "move,move,load,fpload,fpstore")])(define_insn "" [(set (match_operand:SF 0 "general_operand" "=r,*f,d,d,m") (match_operand:SF 1 "fpmove_src_operand" "r,GH,F,m,d"))] "(current_function_args_size != 0 || current_function_stdarg != 0 || rtx_equal_function_value_matters != 0) && (register_operand (operands[0], SFmode) || register_operand (operands[1], SFmode))" "*{ switch (which_alternative) { case 0: if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])) return \"movr %1,%0\"; else return \"mov %1,%0\"; case 1: return \"movr %1,%0\"; case 2: return i960_output_ldconst (operands[0], operands[1]); case 3: return \"ld %1,%0\"; case 4: return \"st %1,%0\"; default: abort(); }}" [(set_attr "type" "move,move,load,fpload,fpstore")]);; Mixed-mode moves with sign and zero-extension.;; Note that the one starting from HImode comes before those for QImode;; so that a constant operand will match HImode, not QImode.(define_expand "extendhisi2" [(set (match_operand:SI 0 "register_operand" "") (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] "" "{ if (GET_CODE (operand1) == REG || (GET_CODE (operand1) == SUBREG && GET_CODE (XEXP (operand1, 0)) == REG)) { rtx temp = gen_reg_rtx (SImode); rtx shift_16 = GEN_INT (16); int op1_subreg_byte = 0; if (GET_CODE (operand1) == SUBREG) { op1_subreg_byte = SUBREG_BYTE (operand1); op1_subreg_byte /= GET_MODE_SIZE (SImode); op1_subreg_byte *= GET_MODE_SIZE (SImode); operand1 = SUBREG_REG (operand1); } if (GET_MODE (operand1) != SImode) operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_byte); emit_insn (gen_ashlsi3 (temp, operand1, shift_16)); emit_insn (gen_ashrsi3 (operand0, temp, shift_16)); DONE; }}")(define_insn "" [(set (match_operand:SI 0 "register_operand" "=d") (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))] "" "ldis %1,%0" [(set_attr "type" "load")])(define_expand "extendqisi2" [(set (match_operand:SI 0 "register_operand" "") (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))] "" "{ if (GET_CODE (operand1) == REG || (GET_CODE (operand1) == SUBREG && GET_CODE (XEXP (operand1, 0)) == REG)) { rtx temp = gen_reg_rtx (SImode); rtx shift_24 = GEN_INT (24); int op1_subreg_byte = 0; if (GET_CODE (operand1) == SUBREG) { op1_subreg_byte = SUBREG_BYTE (operand1); op1_subreg_byte /= GET_MODE_SIZE (SImode); op1_subreg_byte *= GET_MODE_SIZE (SImode); operand1 = SUBREG_REG (operand1); } if (GET_MODE (operand1) != SImode) operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_byte); emit_insn (gen_ashlsi3 (temp, operand1, shift_24)); emit_insn (gen_ashrsi3 (operand0, temp, shift_24)); DONE; }}")(define_insn "" [(set (match_operand:SI 0 "register_operand" "=d") (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))] "" "ldib %1,%0" [(set_attr "type" "load")])(define_expand "extendqihi2" [(set (match_operand:HI 0 "register_operand" "") (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))] "" "{ if (GET_CODE (operand1) == REG || (GET_CODE (operand1) == SUBREG && GET_CODE (XEXP (operand1, 0)) == REG)) { rtx temp = gen_reg_rtx (SImode); rtx shift_24 = GEN_INT (24); int op0_subreg_byte = 0; int op1_subreg_byte = 0; if (GET_CODE (operand1) == SUBREG) { op1_subreg_byte = SUBREG_BYTE (operand1); op1_subreg_byte /= GET_MODE_SIZE (SImode); op1_subreg_byte *= GET_MODE_SIZE (SImode); operand1 = SUBREG_REG (operand1); } if (GET_MODE (operand1) != SImode) operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_byte); if (GET_CODE (operand0) == SUBREG) { op0_subreg_byte = SUBREG_BYTE (operand0); op0_subreg_byte /= GET_MODE_SIZE (SImode); op0_subreg_byte *= GET_MODE_SIZE (SImode); operand0 = SUBREG_REG (operand0); } if (GET_MODE (operand0) != SImode) operand0 = gen_rtx_SUBREG (SImode, operand0, op0_subreg_byte); emit_insn (gen_ashlsi3 (temp, operand1, shift_24)); emit_insn (gen_ashrsi3 (operand0, temp, shift_24)); DONE; }}")(define_insn "" [(set (match_operand:HI 0 "register_operand" "=d") (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))] "" "ldib %1,%0" [(set_attr "type" "load")])(define_expand "zero_extendhisi2" [(set (match_operand:SI 0 "register_operand" "") (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] "" "{ if (GET_CODE (operand1) == REG || (GET_CODE (operand1) == SUBREG && GET_CODE (XEXP (operand1, 0)) == REG)) { rtx temp = gen_reg_rtx (SImode); rtx shift_16 = GEN_INT (16); int op1_subreg_byte = 0; if (GET_CODE (operand1) == SUBREG) { op1_subreg_byte = SUBREG_BYTE (operand1); op1_subreg_byte /= GET_MODE_SIZE (SImode); op1_subreg_byte *= GET_MODE_SIZE (SImode); operand1 = SUBREG_REG (operand1); } if (GET_MODE (operand1) != SImode) operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_byte); emit_insn (gen_ashlsi3 (temp, operand1, shift_16)); emit_insn (gen_lshrsi3 (operand0, temp, shift_16)); DONE; }}")(define_insn "" [(set (match_operand:SI 0 "register_operand" "=d") (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))] "" "ldos %1,%0" [(set_attr "type" "load")]);; Using shifts here generates much better code than doing an `and 255'.;; This is mainly because the `and' requires loading the constant separately,;; the constant is likely to get optimized, and then the compiler can't;; optimize the `and' because it doesn't know that one operand is a constant.(define_expand "zero_extendqisi2" [(set (match_operand:SI 0 "register_operand" "") (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))] "" "{ if (GET_CODE (operand1) == REG || (GET_CODE (operand1) == SUBREG && GET_CODE (XEXP (operand1, 0)) == REG)) { rtx temp = gen_reg_rtx (SImode); rtx shift_24 = GEN_INT (24); int op1_subreg_byte = 0; if (GET_CODE (operand1) == SUBREG) { op1_subreg_byte = SUBREG_BYTE (operand1); op1_subreg_byte /= GET_MODE_SIZE (SImode); op1_subreg_byte *= GET_MODE_SIZE (SImode); operand1 = SUBREG_REG (operand1); } if (GET_MODE (operand1) != SImode) operand1 = gen_rtx (SUBREG, SImode, operand1, op1_subreg_byte); emit_insn (gen_ashlsi3 (temp, operand1, shift_24)); emit_insn (gen_lshrsi3 (operand0, temp, shift_24)); DONE; }}")
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -