📄 iq2000.md
字号:
;; Those for integer source operand are ordered widest source type first.;; These patterns originally accepted general_operands, however, slightly;; better code is generated by only accepting register_operands, and then;; letting combine generate the lh and lb insns.(define_expand "extendhisi2" [(set (match_operand:SI 0 "register_operand" "") (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] "" "{ if (optimize && GET_CODE (operands[1]) == MEM) operands[1] = force_not_mem (operands[1]); if (GET_CODE (operands[1]) != MEM) { rtx op1 = gen_lowpart (SImode, operands[1]); rtx temp = gen_reg_rtx (SImode); rtx shift = GEN_INT (16); emit_insn (gen_ashlsi3 (temp, op1, shift)); emit_insn (gen_ashrsi3 (operands[0], temp, shift)); DONE; }}")(define_insn "extendhisi2_internal" [(set (match_operand:SI 0 "register_operand" "=d,d") (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,m")))] "" "* return iq2000_move_1word (operands, insn, FALSE);" [(set_attr "type" "load") (set_attr "mode" "SI") (set_attr "length" "4,8")])(define_expand "extendqihi2" [(set (match_operand:HI 0 "register_operand" "") (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))] "" "{ if (optimize && GET_CODE (operands[1]) == MEM) operands[1] = force_not_mem (operands[1]); if (GET_CODE (operands[1]) != MEM) { rtx op0 = gen_lowpart (SImode, operands[0]); rtx op1 = gen_lowpart (SImode, operands[1]); rtx temp = gen_reg_rtx (SImode); rtx shift = GEN_INT (24); emit_insn (gen_ashlsi3 (temp, op1, shift)); emit_insn (gen_ashrsi3 (op0, temp, shift)); DONE; }}")(define_insn "extendqihi2_internal" [(set (match_operand:HI 0 "register_operand" "=d,d") (sign_extend:HI (match_operand:QI 1 "memory_operand" "R,m")))] "" "* return iq2000_move_1word (operands, insn, FALSE);" [(set_attr "type" "load") (set_attr "mode" "SI") (set_attr "length" "4,8")])(define_expand "extendqisi2" [(set (match_operand:SI 0 "register_operand" "") (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))] "" "{ if (optimize && GET_CODE (operands[1]) == MEM) operands[1] = force_not_mem (operands[1]); if (GET_CODE (operands[1]) != MEM) { rtx op1 = gen_lowpart (SImode, operands[1]); rtx temp = gen_reg_rtx (SImode); rtx shift = GEN_INT (24); emit_insn (gen_ashlsi3 (temp, op1, shift)); emit_insn (gen_ashrsi3 (operands[0], temp, shift)); DONE; }}")(define_insn "extendqisi2_insn" [(set (match_operand:SI 0 "register_operand" "=d,d") (sign_extend:SI (match_operand:QI 1 "memory_operand" "R,m")))] "" "* return iq2000_move_1word (operands, insn, FALSE);" [(set_attr "type" "load") (set_attr "mode" "SI") (set_attr "length" "4,8")]);;;; ........................;;;; BIT FIELD EXTRACTION;;;; ........................(define_insn "extzv" [(set (match_operand:SI 0 "register_operand" "=r") (zero_extract:SI (match_operand:SI 1 "register_operand" "r") (match_operand:SI 2 "const_int_operand" "O") (match_operand:SI 3 "const_int_operand" "O")))] "" "*{ int value[4]; value[2] = INTVAL (operands[2]); value[3] = INTVAL (operands[3]); operands[2] = GEN_INT ((value[3])); operands[3] = GEN_INT ((32 - value[2])); return \"ram\\t%0,%1,%2,%3,0x0\"; }" [(set_attr "type" "arith")]);;;; ....................;;;; DATA MOVEMENT;;;; ..................../* Take care of constants that don't fit in single instruction */(define_split [(set (match_operand:SI 0 "register_operand" "") (match_operand:SI 1 "general_operand" ""))] "(reload_in_progress || reload_completed) && large_int (operands[1], SImode)" [(set (match_dup 0 ) (high:SI (match_dup 1))) (set (match_dup 0 ) (lo_sum:SI (match_dup 0) (match_dup 1)))]);; ??? iq2000_move_1word has support for HIGH, so this pattern may be;; unnecessary.(define_insn "high" [(set (match_operand:SI 0 "register_operand" "=r") (high:SI (match_operand:SI 1 "immediate_operand" "")))] "" "lui\\t%0,%%hi(%1) # high" [(set_attr "type" "move")])(define_insn "low" [(set (match_operand:SI 0 "register_operand" "=r") (lo_sum:SI (match_operand:SI 1 "register_operand" "r") (match_operand:SI 2 "immediate_operand" "")))] "" "addiu\\t%0,%1,%%lo(%2) # low" [(set_attr "type" "arith") (set_attr "mode" "SI")]);; 32-bit Integer moves(define_split [(set (match_operand:SI 0 "register_operand" "") (match_operand:SI 1 "large_int" ""))] "reload_in_progress | reload_completed" [(set (match_dup 0) (match_dup 2)) (set (match_dup 0) (ior:SI (match_dup 0) (match_dup 3)))] "{ operands[2] = GEN_INT (trunc_int_for_mode (INTVAL (operands[1]) & BITMASK_UPPER16, SImode)); operands[3] = GEN_INT (INTVAL (operands[1]) & BITMASK_LOWER16);}");; Unlike most other insns, the move insns can't be split with;; different predicates, because register spilling and other parts of;; the compiler, have memoized the insn number already.(define_expand "movsi" [(set (match_operand:SI 0 "nonimmediate_operand" "") (match_operand:SI 1 "general_operand" ""))] "" "{ if (iq2000_check_split (operands[1], SImode)) { enum machine_mode mode = GET_MODE (operands[0]); rtx tem = ((reload_in_progress | reload_completed) ? operands[0] : gen_reg_rtx (mode)); emit_insn (gen_rtx_SET (VOIDmode, tem, gen_rtx_HIGH (mode, operands[1]))); operands[1] = gen_rtx_LO_SUM (mode, tem, operands[1]); } if ((reload_in_progress | reload_completed) == 0 && !register_operand (operands[0], SImode) && !register_operand (operands[1], SImode) && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)) { rtx temp = force_reg (SImode, operands[1]); emit_move_insn (operands[0], temp); DONE; } /* Take care of constants that don't fit in single instruction */ if ((reload_in_progress || reload_completed) && CONSTANT_P (operands[1]) && GET_CODE (operands[1]) != HIGH && GET_CODE (operands[1]) != LO_SUM && ! SMALL_INT_UNSIGNED (operands[1])) { rtx tem = ((reload_in_progress | reload_completed) ? operands[0] : gen_reg_rtx (SImode)); emit_insn (gen_rtx_SET (VOIDmode, tem, gen_rtx_HIGH (SImode, operands[1]))); operands[1] = gen_rtx_LO_SUM (SImode, tem, operands[1]); }}");; The difference between these two is whether or not ints are allowed;; in FP registers (off by default, use -mdebugh to enable).(define_insn "movsi_internal2" [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,R,m,*d,*z,*x,*d,*x,*d") (match_operand:SI 1 "move_operand" "d,S,IKL,Mnis,R,m,dJ,dJ,*z,*d,J,*x,*d,*a"))] "(register_operand (operands[0], SImode) || register_operand (operands[1], SImode) || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))" "* return iq2000_move_1word (operands, insn, FALSE);" [(set_attr "type" "move,load,arith,arith,load,load,store,store,xfer,xfer,move,move,move,move") (set_attr "mode" "SI") (set_attr "length" "4,8,4,8,4,8,4,8,4,4,4,4,4,4")]);; 16-bit Integer moves;; Unlike most other insns, the move insns can't be split with;; different predicates, because register spilling and other parts of;; the compiler, have memoized the insn number already.;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined(define_expand "movhi" [(set (match_operand:HI 0 "nonimmediate_operand" "") (match_operand:HI 1 "general_operand" ""))] "" "{ if ((reload_in_progress | reload_completed) == 0 && !register_operand (operands[0], HImode) && !register_operand (operands[1], HImode) && ((GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0))) { rtx temp = force_reg (HImode, operands[1]); emit_move_insn (operands[0], temp); DONE; }}");; The difference between these two is whether or not ints are allowed;; in FP registers (off by default, use -mdebugh to enable).(define_insn "movhi_internal2" [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d") (match_operand:HI 1 "general_operand" "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))] "(register_operand (operands[0], HImode) || register_operand (operands[1], HImode) || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))" "* return iq2000_move_1word (operands, insn, TRUE);" [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,move,move") (set_attr "mode" "HI") (set_attr "length" "4,4,4,8,4,8,4,4,4,4")]);; 8-bit Integer moves;; Unlike most other insns, the move insns can't be split with;; different predicates, because register spilling and other parts of;; the compiler, have memoized the insn number already.;; Unsigned loads are used because BYTE_LOADS_ZERO_EXTEND is defined(define_expand "movqi" [(set (match_operand:QI 0 "nonimmediate_operand" "") (match_operand:QI 1 "general_operand" ""))] "" "{ if ((reload_in_progress | reload_completed) == 0 && !register_operand (operands[0], QImode) && !register_operand (operands[1], QImode) && (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) != 0)) { rtx temp = force_reg (QImode, operands[1]); emit_move_insn (operands[0], temp); DONE; }}");; The difference between these two is whether or not ints are allowed;; in FP registers (off by default, use -mdebugh to enable).(define_insn "movqi_internal2" [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,d,R,m,*d,*z,*x,*d") (match_operand:QI 1 "general_operand" "d,IK,R,m,dJ,dJ,*z,*d,*d,*x"))] "(register_operand (operands[0], QImode) || register_operand (operands[1], QImode) || (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) == 0))" "* return iq2000_move_1word (operands, insn, TRUE);" [(set_attr "type" "move,arith,load,load,store,store,xfer,xfer,move,move") (set_attr "mode" "QI") (set_attr "length" "4,4,4,8,4,8,4,4,4,4")]);; 32-bit floating point moves(define_expand "movsf" [(set (match_operand:SF 0 "general_operand" "") (match_operand:SF 1 "general_operand" ""))] "" "{ if (!reload_in_progress && !reload_completed && GET_CODE (operands[0]) == MEM && (GET_CODE (operands[1]) == MEM || GET_CODE (operands[1]) == CONST_DOUBLE)) operands[1] = copy_to_mode_reg (SFmode, operands[1]); /* Take care of reg <- SF constant */ if ( const_double_operand (operands[1], GET_MODE (operands[1]) ) ) { emit_insn (gen_movsf_high (operands[0], operands[1])); emit_insn (gen_movsf_lo_sum (operands[0], operands[0], operands[1])); DONE; }}")(define_insn "movsf_lo_sum" [(set (match_operand:SF 0 "register_operand" "=r") (lo_sum:SF (match_operand:SF 1 "register_operand" "r") (match_operand:SF 2 "const_double_operand" "")))] "" "*{ REAL_VALUE_TYPE r; long i; REAL_VALUE_FROM_CONST_DOUBLE (r, operands[2]); REAL_VALUE_TO_TARGET_SINGLE (r, i); operands[2] = GEN_INT (i); return \"addiu\\t%0,%1,%%lo(%2) # low\";}" [(set_attr "length" "4") (set_attr "type" "arith")])(define_insn "movsf_high" [(set (match_operand:SF 0 "register_operand" "=r") (high:SF (match_operand:SF 1 "const_double_operand" "")))] "" "*{ REAL_VALUE_TYPE r; long i; REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]); REAL_VALUE_TO_TARGET_SINGLE (r, i); operands[1] = GEN_INT (i); return \"lui\\t%0,%%hi(%1) # high\";}" [(set_attr "length" "4") (set_attr "type" "arith")])(define_insn "*movsf_internal" [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m") (match_operand:SF 1 "nonimmediate_operand" "r,m,r"))] "!memory_operand (operands[0], SFmode) || !memory_operand (operands[1], SFmode)" "*{ iq2000_fill_delay_slot (\"\", DELAY_LOAD, operands, insn); if (which_alternative == 0) return \"or\\t%0,%1,%1\"; else if (which_alternative == 1) return \"lw\\t%0,%1\"; else if (which_alternative == 2) return \"sw\\t%1,%0\";}" [(set_attr "length" "4,4,4") (set_attr "type" "arith,load,store")]);;;; ....................;;;; SHIFTS;;;; ....................(define_expand "ashlsi3" [(set (match_operand:SI 0 "register_operand" "=d") (ashift:SI (match_operand:SI 1 "register_operand" "d") (match_operand:SI 2 "arith_operand" "dI")))] "" "")(define_insn "ashlsi3_internal1" [(set (match_operand:SI 0 "register_operand" "=d") (ashift:SI (match_operand:SI 1 "register_operand" "d") (match_operand:SI 2 "arith_operand" "dI")))] "" "*{ if (GET_CODE (operands[2]) == CONST_INT) { operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); return \"sll\\t%0,%1,%2\"; } else return \"sllv\\t%0,%1,%2\";}" [(set_attr "type" "arith") (set_attr "mode" "SI")])(define_expand "ashrsi3" [(set (match_operand:SI 0 "register_operand" "=d") (ashiftrt:SI (match_operand:SI 1 "register_operand" "d") (match_operand:SI 2 "arith_operand" "dI")))] "" "")(define_insn "ashrsi3_internal1" [(set (match_operand:SI 0 "register_operand" "=d") (ashiftrt:SI (match_operand:SI 1 "register_operand" "d") (match_operand:SI 2 "arith_operand" "dI")))] "" "*{ if (GET_CODE (operands[2]) == CONST_INT) { operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); return \"sra\\t%0,%1,%2\"; } else return \"srav\\t%0,%1,%2\";}" [(set_attr "type" "arith") (set_attr "mode" "SI")])(define_expand "lshrsi3" [(set (match_operand:SI 0 "register_operand" "=d") (lshiftrt:SI (match_operand:SI 1 "register_operand" "d") (match_operand:SI 2 "arith_operand" "dI")))] "" "")(define_insn "lshrsi3_internal1" [(set (match_operand:SI 0 "register_operand" "=d") (lshiftrt:SI (match_operand:SI 1 "register_operand" "d") (match_operand:SI 2 "arith_operand" "dI")))] "" "*{ if (GET_CODE (operands[2]) == CONST_INT) { operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f); return \"srl\\t%0,%1,%2\"; } else return \"srlv\\t%0,%1,%2\";}" [(set_attr "type" "arith") (set_attr "mode" "SI")]);; Rotate Right(define_insn "rotrsi3" [(set (match_operand:SI 0 "register_operand" "=r") (rotatert:SI (match_operand:SI 1 "register_operand" "r") (match_operand:SI 2 "uns_arith_operand" "O")))] "" "ram %0,%1,%2,0x0,0x0" [(set_attr "type" "arith")]);;;; ....................;;;; COMPARISONS;;;; ....................
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -