📄 mt.md
字号:
&& !register_operand (operands[0], SImode) && !register_operand (operands[1], SImode)) operands[1] = copy_to_mode_reg (SImode, operands[1]); /* Take care of constants that don't fit in single instruction */ if ( (reload_in_progress || reload_completed) && !single_const_operand (operands[1], SImode)) { emit_insn (gen_movsi_high (operands[0], operands[1])); emit_insn (gen_movsi_lo_sum (operands[0], operands[0], operands[1])); DONE; }}")(define_insn "movsi_high" [(set (match_operand:SI 0 "register_operand" "=r") (high:SI (match_operand:SI 1 "general_operand" "i")))] "" "*{ return \"ldui\\t%0, %H1\";}" [(set_attr "length" "4") (set_attr "type" "arith")])(define_insn "movsi_lo_sum" [(set (match_operand:SI 0 "register_operand" "=r") (lo_sum:SI (match_operand:SI 1 "register_operand" "r") (match_operand:SI 2 "general_operand" "i")))] "" "*{ return \"addui\\t%0, %1, %L2\";}" [(set_attr "length" "4") (set_attr "type" "arith")])/* 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) && !single_const_operand (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)))]);; The last pattern in movsi (with two instructions);; is really handled by the emit_insn's in movsi;; and the define_split above. This provides additional;; instructions to fill delay slots.;; Note - it is best to only have one movsi pattern and to handle;; all the various contingencies by the use of alternatives. This;; allows reload the greatest amount of flexibility (since reload will;; only choose amoungst alternatives for a selected insn, it will not;; replace the insn with another one).(define_insn "*movsi_internal" [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m,r,r,r,r,r") (match_operand:SI 1 "general_operand" "r,m,r,I,P,L,N,i"))] "(!memory_operand (operands[0], SImode) || !memory_operand (operands[1], SImode)) && !((reload_in_progress || reload_completed) && !single_const_operand (operands[1], SImode))" "@ or %0, %1, %1 ldw %0, %1 stw %1, %0 addi %0, r0, %1 addui %0, r0, %1 ldui %0, %H1 nori %0, r0, %N1 ldui %0, %H1\;addui %0, %0, %L1" [(set_attr "length" "4,4,4,4,4,4,4,8") (set_attr "type" "arith,load,store,arith,arith,arith,arith,complex")]);; Floating Point Moves;;;; Note - Patterns for SF mode moves are compulsory, but;; patterns for DF are optional, as GCC can synthesize them.(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 \"addui\\t%0, %1, %L2\";}" [(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 \"ldui\\t%0, %H1\";}" [(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)" "@ or %0, %1, %1 ldw %0, %1 stw %1, %0" [(set_attr "length" "4,4,4") (set_attr "type" "arith,load,store")])(define_expand "movdf" [(set (match_operand:DF 0 "general_operand" "") (match_operand:DF 1 "general_operand" ""))] "" "{ /* One of the ops has to be in a register or 0 */ if (!register_operand (operand0, DFmode) && !reg_or_0_operand (operand1, DFmode)) operands[1] = copy_to_mode_reg (DFmode, operand1);}")(define_insn_and_split "*movdf_internal" [(set (match_operand:DF 0 "nonimmediate_operand" "=r,o") (match_operand:DF 1 "general_operand" "rim,r"))] "! (memory_operand (operands[0], DFmode) && memory_operand (operands[1], DFmode))" "#" "(reload_completed || reload_in_progress)" [(set (match_dup 2) (match_dup 3)) (set (match_dup 4) (match_dup 5)) ] "{ /* figure out what precisely to put into operands 2, 3, 4, and 5 */ mt_split_words (SImode, DFmode, operands); }");; Reloads;; Like `movM', but used when a scratch register is required to move between;; operand 0 and operand 1. Operand 2 describes the scratch register. See the;; discussion of the `SECONDARY_RELOAD_CLASS' macro.(define_expand "reload_inqi" [(set (match_operand:QI 0 "register_operand" "=r") (match_operand:QI 1 "memory_operand" "m")) (clobber (match_operand:DI 2 "register_operand" "=&r"))] "! TARGET_BYTE_ACCESS" "{ rtx scratch1 = gen_rtx_REG (SImode, REGNO (operands[2])); rtx scratch2 = gen_rtx_REG (SImode, REGNO (operands[2])+1); rtx data = operands[0]; rtx address = XEXP (operands[1], 0); rtx swap, seq; /* It is possible that the registers we got for scratch1 might coincide with that of operands[0]. gen_loadqi requires operand0 and operand2 to be different registers. The following statement ensure that is always the case. */ if (REGNO(operands[0]) == REGNO(scratch1)) { swap = scratch1; scratch1 = scratch2; scratch2 = swap; } /* need to make sure address is already in register */ if ( GET_CODE (address) != REG ) address = force_operand (address, scratch2); start_sequence (); emit_insn (gen_loadqi (gen_lowpart (SImode, data), address, scratch1)); mt_set_memflags (operands[1]); seq = get_insns (); end_sequence (); emit_insn (seq); DONE;}")(define_expand "reload_outqi" [(set (match_operand:QI 0 "memory_operand" "=m") (match_operand:QI 1 "register_operand" "r")) (clobber (match_operand:TI 2 "register_operand" "=&r"))] "! TARGET_BYTE_ACCESS" "{ rtx scratch1 = gen_rtx_REG (SImode, REGNO (operands[2])); rtx scratch2 = gen_rtx_REG (SImode, REGNO (operands[2])+1); rtx scratch3 = gen_rtx_REG (SImode, REGNO (operands[2])+2); rtx scratch4 = gen_rtx_REG (SImode, REGNO (operands[2])+3); rtx data = operands[1]; rtx address = XEXP (operands[0], 0); rtx seq; /* need to make sure address is already in register */ if ( GET_CODE (address) != REG ) address = force_operand (address, scratch4); start_sequence (); emit_insn (gen_storeqi (gen_lowpart (SImode, data), address, scratch1, scratch2, scratch3)); mt_set_memflags (operands[0]); seq = get_insns (); end_sequence (); emit_insn (seq); DONE;}")(define_expand "reload_inhi" [(set (match_operand:HI 0 "register_operand" "=r") (match_operand:HI 1 "memory_operand" "m")) (clobber (match_operand:DI 2 "register_operand" "=&r"))] "" "{ rtx scratch1 = gen_rtx_REG (SImode, REGNO (operands[2])); rtx scratch2 = gen_rtx_REG (SImode, REGNO (operands[2])+1); rtx data = operands[0]; rtx address = XEXP (operands[1], 0); rtx swap, seq; /* It is possible that the registers we got for scratch1 might coincide with that of operands[0]. gen_loadqi requires operand0 and operand2 to be different registers. The following statement ensure that is always the case. */ if (REGNO(operands[0]) == REGNO(scratch1)) { swap = scratch1; scratch1 = scratch2; scratch2 = swap; } /* need to make sure address is already in register */ if ( GET_CODE (address) != REG ) address = force_operand (address, scratch2); start_sequence (); emit_insn (gen_loadhi (gen_lowpart (SImode, data), address, scratch1)); mt_set_memflags (operands[1]); seq = get_insns (); end_sequence (); emit_insn (seq); DONE;}")(define_expand "reload_outhi" [(set (match_operand:HI 0 "memory_operand" "=m") (match_operand:HI 1 "register_operand" "r")) (clobber (match_operand:TI 2 "register_operand" "=&r"))] "" "{ rtx scratch1 = gen_rtx_REG (SImode, REGNO (operands[2])); rtx scratch2 = gen_rtx_REG (SImode, REGNO (operands[2])+1); rtx scratch3 = gen_rtx_REG (SImode, REGNO (operands[2])+2); rtx scratch4 = gen_rtx_REG (SImode, REGNO (operands[2])+3); rtx data = operands[1]; rtx address = XEXP (operands[0], 0); rtx seq; /* need to make sure address is already in register */ if ( GET_CODE (address) != REG ) address = force_operand (address, scratch4); start_sequence (); emit_insn (gen_storehi (gen_lowpart (SImode, data), address, scratch1, scratch2, scratch3)); mt_set_memflags (operands[0]); seq = get_insns (); end_sequence (); emit_insn (seq); DONE;}");; 32 bit Integer arithmetic;; Addition(define_insn "addsi3" [(set (match_operand:SI 0 "register_operand" "=r,r") (plus:SI (match_operand:SI 1 "register_operand" "%r,r") (match_operand:SI 2 "arith_operand" "r,I")))] "" "@ add %0, %1, %2 addi %0, %1, %2" [(set_attr "length" "4,4") (set_attr "type" "arith,arith")]);; Subtraction(define_insn "subsi3" [(set (match_operand:SI 0 "register_operand" "=r,r") (minus:SI (match_operand:SI 1 "reg_or_0_operand" "rJ,rJ") (match_operand:SI 2 "arith_operand" "rJ,I")))] "" "@ sub %0, %z1, %z2 subi %0, %z1, %2" [(set_attr "length" "4,4") (set_attr "type" "arith,arith")]);; Negation (define_insn "negsi2" [(set (match_operand:SI 0 "register_operand" "=r,r") (neg:SI (match_operand:SI 1 "arith_operand" "r,I")))] "" "@ sub %0, r0, %1 subi %0, r0, %1" [(set_attr "length" "4,4") (set_attr "type" "arith,arith")]);; 32 bit Integer Shifts and Rotates;; Arithmetic Shift Left(define_insn "ashlsi3" [(set (match_operand:SI 0 "register_operand" "=r,r") (ashift:SI (match_operand:SI 1 "register_operand" "r,r") (match_operand:SI 2 "arith_operand" "r,K")))] "" "@ lsl %0, %1, %2 lsli %0, %1, %2" [(set_attr "length" "4,4") (set_attr "type" "arith,arith")]);; Arithmetic Shift Right(define_insn "ashrsi3" [(set (match_operand:SI 0 "register_operand" "=r,r") (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,r") (match_operand:SI 2 "uns_arith_operand" "r,K")))] "" "@ asr %0, %1, %2 asri %0, %1, %2" [(set_attr "length" "4,4") (set_attr "type" "arith,arith")]);; Logical Shift Right(define_insn "lshrsi3" [(set (match_operand:SI 0 "register_operand" "=r,r") (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r") (match_operand:SI 2 "uns_arith_operand" "r,K")))] "" "@ lsr %0, %1, %2 lsri %0, %1, %2" [(set_attr "length" "4,4") (set_attr "type" "arith,arith")]);; 32 Bit Integer Logical operations;; Logical AND, 32 bit integers(define_insn "andsi3" [(set (match_operand:SI 0 "register_operand" "=r,r") (and:SI (match_operand:SI 1 "register_operand" "%r,r") (match_operand:SI 2 "uns_arith_operand" "r,K")))] "" "@ and %0, %1, %2 andi %0, %1, %2" [(set_attr "length" "4,4") (set_attr "type" "arith,arith")]);; Inclusive OR, 32 bit integers(define_insn "iorsi3" [(set (match_operand:SI 0 "register_operand" "=r,r") (ior:SI (match_operand:SI 1 "register_operand" "%r,r") (match_operand:SI 2 "uns_arith_operand" "r,K")))] "" "@ or %0, %1, %2 ori %0, %1, %2" [(set_attr "length" "4,4") (set_attr "type" "arith,arith")]);; Exclusive OR, 32 bit integers(define_insn "xorsi3" [(set (match_operand:SI 0 "register_operand" "=r,r") (xor:SI (match_operand:SI 1 "register_operand" "%r,r") (match_operand:SI 2 "uns_arith_operand" "r,K")))] "" "@ xor %0, %1, %2 xori %0, %1, %2" [(set_attr "length" "4,4") (set_attr "type" "arith,arith")]);; One's complement, 32 bit integers(define_insn "one_cmplsi2" [(set (match_operand:SI 0 "register_operand" "=r") (not:SI (match_operand:SI 1 "register_operand" "r")))] "" "nor %0, %1, %1" [(set_attr "length" "4") (set_attr "type" "arith")]);; Multiply(define_insn "mulhisi3" [(set (match_operand:SI 0 "register_operand" "=r,r") (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%r,r")) (sign_extend:SI (match_operand:HI 2 "arith_operand" "r,I"))))] "TARGET_MS1_16_003 || TARGET_MS2" "@ mul %0, %1, %2 muli %0, %1, %2" [(set_attr "length" "4,4") (set_attr "type" "arith,arith")]);; Comparisons;; Note, we store the operands in the comparison insns, and use them later;; when generating the branch or scc operation.;; First the routines called by the machine independent part of the compiler(define_expand "cmpsi" [(set (cc0) (compare (match_operand:SI 0 "register_operand" "") (match_operand:SI 1 "arith_operand" "")))] "" "{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -