📄 arm.md
字号:
(fix:SI (match_operand:SF 1 "s_register_operand" "f")))] "TARGET_HARD_FLOAT" "fix%?z\\t%0, %1"[(set_attr "type" "f_2_r")])(define_insn "fix_truncdfsi2" [(set (match_operand:SI 0 "s_register_operand" "=r") (fix:SI (match_operand:DF 1 "s_register_operand" "f")))] "TARGET_HARD_FLOAT" "fix%?z\\t%0, %1"[(set_attr "type" "f_2_r")])(define_insn "fix_truncxfsi2" [(set (match_operand:SI 0 "s_register_operand" "=r") (fix:SI (match_operand:XF 1 "s_register_operand" "f")))] "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT" "fix%?z\\t%0, %1"[(set_attr "type" "f_2_r")]);; Truncation insns(define_insn "truncdfsf2" [(set (match_operand:SF 0 "s_register_operand" "=f") (float_truncate:SF (match_operand:DF 1 "s_register_operand" "f")))] "TARGET_HARD_FLOAT" "mvf%?s\\t%0, %1"[(set_attr "type" "ffarith")])(define_insn "truncxfsf2" [(set (match_operand:SF 0 "s_register_operand" "=f") (float_truncate:SF (match_operand:XF 1 "s_register_operand" "f")))] "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT" "mvf%?s\\t%0, %1"[(set_attr "type" "ffarith")])(define_insn "truncxfdf2" [(set (match_operand:DF 0 "s_register_operand" "=f") (float_truncate:DF (match_operand:XF 1 "s_register_operand" "f")))] "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT" "mvf%?d\\t%0, %1"[(set_attr "type" "ffarith")]);; Zero and sign extension instructions.(define_insn "zero_extendsidi2" [(set (match_operand:DI 0 "s_register_operand" "=r") (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r")))] "" "* if (REGNO (operands[1]) != REGNO (operands[0])) output_asm_insn (\"mov%?\\t%0, %1\", operands); return \"mov%?\\t%R0, #0\";"[(set_attr "length" "8")])(define_insn "zero_extendqidi2" [(set (match_operand:DI 0 "s_register_operand" "=r,r") (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))] "" "@ and%?\\t%0, %1, #255\;mov%?\\t%R0, #0 ldr%?b\\t%0, %1\;mov%?\\t%R0, #0"[(set_attr "length" "8") (set_attr "type" "*,load")])(define_insn "extendsidi2" [(set (match_operand:DI 0 "s_register_operand" "=r") (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r")))] "" "* if (REGNO (operands[1]) != REGNO (operands[0])) output_asm_insn (\"mov%?\\t%0, %1\", operands); return \"mov%?\\t%R0, %0, asr #31\";"[(set_attr "length" "8")])(define_expand "zero_extendhisi2" [(set (match_dup 2) (ashift:SI (match_operand:HI 1 "nonimmediate_operand" "") (const_int 16))) (set (match_operand:SI 0 "s_register_operand" "") (lshiftrt:SI (match_dup 2) (const_int 16)))] "" "{ if (TARGET_SHORT_BY_BYTES && GET_CODE (operands[1]) == MEM) { emit_insn (gen_movhi_bytes (operands[0], operands[1])); DONE; } if (! s_register_operand (operands[1], HImode)) operands[1] = copy_to_mode_reg (HImode, operands[1]); operands[1] = gen_lowpart (SImode, operands[1]); operands[2] = gen_reg_rtx (SImode); }")(define_expand "zero_extendqisi2" [(set (match_operand:SI 0 "s_register_operand" "=r,r") (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))] "" " if (GET_CODE (operands[1]) != MEM) { emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, operands[1]), GEN_INT (255))); DONE; }")(define_insn "" [(set (match_operand:SI 0 "s_register_operand" "=r") (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))] "" "ldr%?b\\t%0, %1\\t%@ zero_extendqisi2"[(set_attr "type" "load")])(define_split [(set (match_operand:SI 0 "s_register_operand" "") (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0))) (clobber (match_operand:SI 2 "s_register_operand" ""))] "GET_CODE (operands[1]) != MEM" [(set (match_dup 2) (match_dup 1)) (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))] "")(define_insn "" [(set (reg:CC_NOOV 24) (compare:CC_NOOV (match_operand:QI 0 "s_register_operand" "r") (const_int 0)))] "" "tst\\t%0, #255"[(set_attr "conds" "set")])(define_expand "extendhisi2" [(set (match_dup 2) (ashift:SI (match_operand:HI 1 "nonimmediate_operand" "") (const_int 16))) (set (match_operand:SI 0 "s_register_operand" "") (ashiftrt:SI (match_dup 2) (const_int 16)))] "" "{ if (TARGET_SHORT_BY_BYTES && GET_CODE (operands[1]) == MEM) { emit_insn (gen_extendhisi2_mem (operands[0], operands[1])); DONE; } if (! s_register_operand (operands[1], HImode)) operands[1] = copy_to_mode_reg (HImode, operands[1]); operands[1] = gen_lowpart (SImode, operands[1]); operands[2] = gen_reg_rtx (SImode);}")(define_expand "extendhisi2_mem" [(set (match_dup 2) (zero_extend:SI (mem:QI (match_operand:HI 1 "" "")))) (set (match_dup 3) (zero_extend:SI (mem:QI (plus:SI (match_dup 1) (const_int 1))))) (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24))) (set (match_operand:SI 0 "" "") (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))] "" " operands[0] = gen_lowpart (SImode, operands[0]); operands[1] = copy_to_mode_reg (SImode, XEXP (operands[1], 0)); operands[2] = gen_reg_rtx (SImode); operands[3] = gen_reg_rtx (SImode); operands[6] = gen_reg_rtx (SImode); if (BYTES_BIG_ENDIAN) { operands[4] = operands[2]; operands[5] = operands[3]; } else { operands[4] = operands[3]; operands[5] = operands[2]; }")(define_expand "extendqihi2" [(set (match_dup 2) (ashift:SI (match_operand:QI 1 "s_register_operand" "") (const_int 24))) (set (match_operand:HI 0 "s_register_operand" "") (ashiftrt:SI (match_dup 2) (const_int 24)))] "" "{ operands[0] = gen_lowpart (SImode, operands[0]); operands[1] = gen_lowpart (SImode, operands[1]); operands[2] = gen_reg_rtx (SImode); }")(define_expand "extendqisi2" [(set (match_dup 2) (ashift:SI (match_operand:QI 1 "s_register_operand" "") (const_int 24))) (set (match_operand:SI 0 "s_register_operand" "") (ashiftrt:SI (match_dup 2) (const_int 24)))] "" "{ operands[1] = gen_lowpart (SImode, operands[1]); operands[2] = gen_reg_rtx (SImode); }")(define_insn "extendsfdf2" [(set (match_operand:DF 0 "s_register_operand" "=f") (float_extend:DF (match_operand:SF 1 "s_register_operand" "f")))] "TARGET_HARD_FLOAT" "mvf%?d\\t%0, %1"[(set_attr "type" "ffarith")])(define_insn "extendsfxf2" [(set (match_operand:XF 0 "s_register_operand" "=f") (float_extend:XF (match_operand:SF 1 "s_register_operand" "f")))] "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT" "mvf%?e\\t%0, %1"[(set_attr "type" "ffarith")])(define_insn "extenddfxf2" [(set (match_operand:XF 0 "s_register_operand" "=f") (float_extend:XF (match_operand:DF 1 "s_register_operand" "f")))] "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT" "mvf%?e\\t%0, %1"[(set_attr "type" "ffarith")]);; Move insns (including loads and stores);; XXX Just some ideas about movti.;; I don't think these are a good idea on the arm, there just aren't enough;; registers;;(define_expand "loadti";; [(set (match_operand:TI 0 "s_register_operand" "");; (mem:TI (match_operand:SI 1 "address_operand" "")))];; "" "");;(define_expand "storeti";; [(set (mem:TI (match_operand:TI 0 "address_operand" ""));; (match_operand:TI 1 "s_register_operand" ""))];; "" "");;(define_expand "movti";; [(set (match_operand:TI 0 "general_operand" "");; (match_operand:TI 1 "general_operand" ""))];; "";; ";;{;; rtx insn;;;;; if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM);; operands[1] = copy_to_reg (operands[1]);;; if (GET_CODE (operands[0]) == MEM);; insn = gen_storeti (XEXP (operands[0], 0), operands[1]);;; else if (GET_CODE (operands[1]) == MEM);; insn = gen_loadti (operands[0], XEXP (operands[1], 0));;; else;; FAIL;;;;; emit_insn (insn);;; DONE;;;}");; Recognise garbage generated above.;;(define_insn "";; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m");; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))];; "";; "*;; {;; register mem = (which_alternative < 3);;; register char *template;;;;; operands[mem] = XEXP (operands[mem], 0);;; switch (which_alternative);; {;; case 0: template = \"ldmdb\\t%1!, %M0\"; break;;; case 1: template = \"ldmia\\t%1!, %M0\"; break;;; case 2: template = \"ldmia\\t%1, %M0\"; break;;; case 3: template = \"stmdb\\t%0!, %M1\"; break;;; case 4: template = \"stmia\\t%0!, %M1\"; break;;; case 5: template = \"stmia\\t%0, %M1\"; break;;; };; output_asm_insn (template, operands);;; return \"\";;; }")(define_insn "movdi" [(set (match_operand:DI 0 "di_operand" "=r,r,r,o<>,r") (match_operand:DI 1 "di_operand" "rIK,n,o<>,r,F"))] "" "* return (output_move_double (operands));"[(set_attr "length" "8,32,8,8,32") (set_attr "type" "*,*,load,store2,*")])(define_expand "movsi" [(set (match_operand:SI 0 "general_operand" "") (match_operand:SI 1 "general_operand" ""))] "" " /* Everything except mem = const or mem = mem can be done easily */ if (GET_CODE (operands[0]) == MEM) operands[1] = force_reg (SImode, operands[1]); if (GET_CODE (operands[1]) == CONST_INT && !(const_ok_for_arm (INTVAL (operands[1])) || const_ok_for_arm (~INTVAL (operands[1])))) { arm_split_constant (SET, SImode, INTVAL (operands[1]), operands[0], NULL_RTX, (reload_in_progress || reload_completed ? 0 : preserve_subexpressions_p ())); DONE; }")(define_insn "" [(set (match_operand:SI 0 "general_operand" "=r,r,r,r,m,r,r") (match_operand:SI 1 "general_operand" "R,m,K,rI,r,S,?n"))] "(register_operand (operands[0], SImode) && (GET_CODE (operands[1]) != SYMBOL_REF || CONSTANT_ADDRESS_P (operands[1]))) || register_operand (operands[1], SImode)" "* switch (which_alternative) { case 0: /* NB Calling get_attr_length may cause the insn to be re-extracted... */ if (get_attr_length (insn) == 8) { /* ... so modify the operands here. */ operands[1] = XEXP (operands[1], 0); output_asm_insn (\"sub%?\\t%0, %|pc, #(8 + . - %a1) & ~4095\", operands); output_asm_insn (\"ldr%?\\t%0, [%0, #- ((4 + . - %a1) & 4095)]\", operands); } else { /* ... and here. */ operands[1] = XEXP (operands[1], 0); output_asm_insn (\"ldr%?\\t%0, [%|pc, %1 - . - 8]\", operands); } return \"\"; case 1: if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))) abort (); return \"ldr%?\\t%0, %1\"; case 3: return \"mov%?\\t%0, %1\"; case 2: return \"mvn%?\\t%0, #%B1\"; case 4: return \"str%?\\t%1, %0\"; case 5: return output_load_symbol (insn, operands); case 6: return \"#\"; }"[(set (attr "length") (cond [(eq_attr "alternative" "0") (if_then_else (gt (minus (pc) (symbol_ref "const_pool_offset (XEXP (operands[1], 0))")) (const_int 4087)) (const_int 8) (const_int 4)) (ior (eq_attr "alternative" "5") (eq_attr "alternative" "6")) (const_int 16)] (const_int 4))) (set_attr "type" "load,load,*,*,store1,*,*")])(define_split [(set (match_operand:SI 0 "s_register_operand" "") (match_operand:SI 1 "const_int_operand" ""))] "! (const_ok_for_arm (INTVAL (operands[1])) || const_ok_for_arm (~INTVAL (operands[1])))" [(clobber (const_int 0))] " arm_split_constant (SET, SImode, INTVAL (operands[1]), operands[0], NULL_RTX, 0); DONE;");; If copying one reg to another we can set the condition codes according to;; its value. Such a move is common after a return from subroutine and the;; result is being tested against zero.(define_insn "" [(set (reg:CC 24) (compare (match_operand:SI 1 "s_register_operand" "0,r") (const_int 0))) (set (match_operand:SI 0 "s_register_operand" "=r,r") (match_dup 1))] "" "@ cmp%?\\t%0, #0 sub%?s\\t%0, %1, #0"[(set_attr "conds" "set")]);; Subroutine to store a half word from a register into memory.;; Operand 0 is the source register (HImode);; Operand 1 is the destination address in a register (SImode);; In both this routine and the next, we must be careful not to spill;; a memory address of reg+large_const into a separate PLUS insn, since this;; can generate unrecognizable rtl.(define_expand "storehi" [;; store the low byte (set (me
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -