📄 h8300.md
字号:
;; ??? Even though we use HImode here, this works for the 300h.(define_insn "call" [(call (match_operand:QI 0 "call_insn_operand" "or") (match_operand:HI 1 "general_operand" "g"))] "" "jsr %0" [(set_attr "type" "call") (set_attr "cc" "clobber") (set_attr "length" "4")]);; Call subroutine, returning value in operand 0;; (which must be a hard register).;; ??? Even though we use HImode here, this works on the 300h.(define_insn "call_value" [(set (match_operand 0 "" "=r") (call (match_operand:QI 1 "call_insn_operand" "or") (match_operand:HI 2 "general_operand" "g")))] "" "jsr %1" [(set_attr "type" "call") (set_attr "cc" "clobber") (set_attr "length" "4")])(define_insn "nop" [(const_int 0)] "" "nop" [(set_attr "type" "multi") (set_attr "cc" "none") (set_attr "length" "2")]);; ----------------------------------------------------------------------;; EXTEND INSTRUCTIONS;; ----------------------------------------------------------------------(define_insn "zero_extendqihi2" [(set (match_operand:HI 0 "register_operand" "=r,r") (zero_extend:HI (match_operand:QI 1 "general_operand" "0,g")))] "" "*{ if (which_alternative==0) return \"mov.b #0,%t0\"; if (TARGET_H8300) return \"mov.b %X1,%s0\;mov.b #0,%t0\"; else { /* ??? See how often this gets optimized. */ if (REG_P (operands[1]) && (REGNO (operands[1]) == REGNO (operands[0]))) return \"extu.w %T0\"; else return \"mov.b %X1,%s0\;extu.w %T0\"; }}" [(set_attr "type" "multi");; ??? This length is wrong for one case. (set_attr "length" "4") (set_attr "cc" "clobber")])(define_insn "zero_extendhisi2" [(set (match_operand:SI 0 "register_operand" "=r") (zero_extend:SI (match_operand:HI 1 "general_operand" "g")))] "TARGET_H8300H" "*{ /* ??? See how often this gets optimized. */ if (REG_P (operands[1]) && (REGNO (operands[1]) == REGNO (operands[0]))) return \"extu.l %S0\"; else return \"mov.w %T1,%T0\;extu.l %S0\";}" [(set_attr "type" "multi");; ??? This length is wrong for one case. (set_attr "length" "4") (set_attr "cc" "clobber")])(define_insn "extendqihi2" [(set (match_operand:HI 0 "register_operand" "=r") (sign_extend:HI (match_operand:QI 1 "general_operand" "g")))] "" "*{ if (TARGET_H8300) { /* ??? See how often this gets optimized. */ if (REG_P (operands[1]) && (REGNO (operands[1]) == REGNO (operands[0]))) return \"bld #7,%s0\;subx %t0,%t0\"; else return \"mov.b %X1,%s0\;bld #7,%s0\;subx %t0,%t0\"; } else { /* ??? See how often this gets optimized. */ if (REG_P (operands[1]) && (REGNO (operands[1]) == REGNO (operands[0]))) return \"exts.w %T0\"; else return \"mov.b %X1,%s0\;exts.w %T0\"; }}" [(set_attr "type" "multi");; ??? Length is wrong in some cases. (set_attr "length" "6") (set_attr "cc" "clobber")])(define_expand "extendhisi2" [(set (match_operand:SI 0 "register_operand" "") (sign_extend:SI (match_operand:HI 1 "general_operand" "")))] "" "{ if (TARGET_H8300) emit_insn (gen_extendhisi2_h8300 (operands[0], operands[1])); else emit_insn (gen_extendhisi2_h8300h (operands[0], operands[1])); DONE;}")(define_expand "extendhisi2_h8300" [(set (reg:HI 1) (match_operand:HI 1 "general_operand" "")) (set (reg:SI 0) (sign_extend:SI (reg:HI 1))) (set (match_operand:SI 0 "general_operand" "" ) (reg:SI 0))] "TARGET_H8300" "")(define_expand "extendhisi2_h8300h" [(set (match_operand:SI 0 "register_operand" "") (sign_extend:SI (match_operand:HI 1 "general_operand" "")))] "TARGET_H8300H" "")(define_insn "extendhisi2_h8300_internal" [(set (match_operand:SI 0 "register_operand" "=r") (sign_extend:SI (match_operand:HI 1 "register_operand" "0")))] "TARGET_H8300" "mov.w %T1,%f0\;bld #7,%x0\;subx %y0,%y0\;subx %z0,%z0" [(set_attr "length" "10") (set_attr "cc" "clobber")])(define_insn "extendhisi2_h8300h_internal" [(set (match_operand:SI 0 "register_operand" "=r") (sign_extend:SI (match_operand:HI 1 "general_operand" "g")))] "TARGET_H8300H" "*{ /* ??? See how often this gets optimized. */ if (REG_P (operands[1]) && (REGNO (operands[1]) == REGNO (operands[0]))) return \"exts.l %S0\"; else return \"mov.w %T1,%T0\;exts.l %S0\";}" [(set_attr "length" "10") (set_attr "cc" "clobber")]);; ----------------------------------------------------------------------;; SHIFTS;; ----------------------------------------------------------------------;;;; We make some attempt to provide real efficient shifting. One example is;; doing an 8 bit shift of a 16 bit value by moving a byte reg into the other;; reg and moving 0 into the former reg.;;;; We also try to achieve this in a uniform way. IE: We don't try to achieve;; this in both rtl and at insn emit time. Ideally, we'd use rtl as that would;; give the optimizer more cracks at the code. However, we wish to do things;; like optimizing shifting the sign bit to bit 0 by rotating the other way.;; There is rtl to handle this (rotate + and), but the h8/300 doesn't handle;; 16 bit rotates. Also, if we emit complicated rtl, combine may not be able;; to detect cases it can optimize.;;;; For these and other fuzzy reasons, I've decided to go the less pretty but;; easier "do it at insn emit time" route.;; QI BIT SHIFTS(define_expand "ashlqi3" [(set (match_operand:QI 0 "register_operand" "") (ashift:QI (match_operand:QI 1 "register_operand" "") (match_operand:QI 2 "nonmemory_operand" "")))] "" "if (expand_a_shift (QImode, ASHIFT, operands)) DONE;else FAIL;")(define_expand "ashrqi3" [(set (match_operand:QI 0 "register_operand" "") (ashiftrt:QI (match_operand:QI 1 "register_operand" "") (match_operand:QI 2 "nonmemory_operand" "")))] "" "if (expand_a_shift (QImode, ASHIFTRT, operands)) DONE;else FAIL;")(define_expand "lshrqi3" [(set (match_operand:QI 0 "register_operand" "") (lshiftrt:QI (match_operand:QI 1 "register_operand" "") (match_operand:QI 2 "nonmemory_operand" "")))] "" "if (expand_a_shift (QImode, LSHIFTRT, operands)) DONE;else FAIL;");; WARNING: The constraints on the scratch register say one is not needed;; for constant shifts of 1,2,3,4. Emit_a_shift() must know this.(define_insn "shiftbyn_QI" [(set (match_operand:QI 0 "register_operand" "=r,r") (match_operator:QI 3 "nshift_operator" [ (match_operand:QI 1 "register_operand" "0,0") (match_operand:QI 2 "nonmemory_operand" "IKM,rn")])) (clobber (match_scratch:QI 4 "=X,&r"))] "" "* return emit_a_shift (insn, operands);" [(set_attr "type" "arith") (set_attr "length" "20");; ??? We'd like to indicate that cc is set here, and it is for simple shifts.;; However, for cases that loop or are done in pieces, cc does not contain;; what we want. Emit_a_shift is free to tweak cc_status as desired. (set_attr "cc" "clobber")]);; HI BIT SHIFTS(define_expand "ashlhi3" [(set (match_operand:HI 0 "register_operand" "") (ashift:HI (match_operand:HI 1 "nonmemory_operand" "") (match_operand:QI 2 "nonmemory_operand" "")))] "" "if (expand_a_shift (HImode, ASHIFT, operands)) DONE;else FAIL;")(define_expand "lshrhi3" [(set (match_operand:HI 0 "register_operand" "") (lshiftrt:HI (match_operand:HI 1 "general_operand_src" "") (match_operand:QI 2 "nonmemory_operand" "")))] "" "if (expand_a_shift (HImode, LSHIFTRT, operands)) DONE;else FAIL;")(define_expand "ashrhi3" [(set (match_operand:HI 0 "register_operand" "") (ashiftrt:HI (match_operand:HI 1 "register_operand" "") (match_operand:QI 2 "nonmemory_operand" "")))] "" "if (expand_a_shift (HImode, ASHIFTRT, operands)) DONE;else FAIL;");; WARNING: The constraints on the scratch register say one is not needed;; for constant shifts of 1,2,3,4. Emit_a_shift() must know this.(define_insn "shiftbyn_HI" [(set (match_operand:HI 0 "register_operand" "=r,r") (match_operator:HI 3 "nshift_operator" [ (match_operand:HI 1 "register_operand" "0,0") (match_operand:QI 2 "nonmemory_operand" "IKM,rn")])) (clobber (match_scratch:QI 4 "=X,&r"))] "" "* return emit_a_shift (insn, operands);" [(set_attr "type" "arith") (set_attr "length" "20");; ??? We'd like to indicate that cc is set here, and it is for simple shifts.;; However, for cases that loop or are done in pieces, cc does not contain;; what we want. Emit_a_shift is free to tweak cc_status as desired. (set_attr "cc" "clobber")]);; SI BIT SHIFTS(define_expand "ashlsi3" [(set (match_operand:SI 0 "register_operand" "") (ashift:SI (match_operand:SI 1 "general_operand_src" "") (match_operand:QI 2 "nonmemory_operand" "")))] "" "if (expand_a_shift (SImode, ASHIFT, operands)) DONE;else FAIL;")(define_expand "lshrsi3" [(set (match_operand:SI 0 "register_operand" "") (lshiftrt:SI (match_operand:SI 1 "general_operand_src" "") (match_operand:QI 2 "nonmemory_operand" "")))] "" "if (expand_a_shift (SImode, LSHIFTRT, operands)) DONE;else FAIL;")(define_expand "ashrsi3" [(set (match_operand:SI 0 "register_operand" "") (ashiftrt:SI (match_operand:SI 1 "general_operand_src" "") (match_operand:QI 2 "nonmemory_operand" "")))] "" "if (expand_a_shift (SImode, ASHIFTRT, operands)) DONE;else FAIL;");; WARNING: The constraints on the scratch register say one is not needed;; for constant shifts of 1,2. Emit_a_shift() must know this.(define_insn "shiftbyn_SI" [(set (match_operand:SI 0 "register_operand" "=r,r") (match_operator:SI 3 "nshift_operator" [ (match_operand:SI 1 "register_operand" "0,0") (match_operand:QI 2 "nonmemory_operand" "IK,rn")])) (clobber (match_scratch:QI 4 "=X,&r"))] "" "* return emit_a_shift (insn, operands);" [(set_attr "type" "arith") (set_attr "length" "20");; ??? We'd like to indicate that cc is set here, and it is for simple shifts.;; However, for cases that loop or are done in pieces, cc does not contain;; what we want. Emit_a_shift is free to tweak cc_status as desired. (set_attr "cc" "clobber")]);; -----------------------------------------------------------------;; BIT FIELDS;; -----------------------------------------------------------------;; The H8/300 has given 1/8th of its opcode space to bitfield;; instructions so let's use them as well as we can;; BCC and BCS patterns.(define_insn "bcs_qiqi" [(set (pc) (if_then_else (match_operator 1 "eq_operator" [(zero_extract:QI (match_operand:QI 2 "bit_operand" "Ur") (const_int 1) (match_operand:HI 3 "immediate_operand" "i")) (const_int 0)]) (label_ref (match_operand 0 "" "")) (pc)))] "" "*{ output_asm_insn(\"bld %Z3,%Y2\", operands); if (get_attr_length (insn) == 2) return \"b%d1 %l0\"; else if (get_attr_length (insn) == 4) return \"b%d1 %l0:16\"; else return \"b%g1 %L0\;jmp @%l0\;%L0:\";}" [(set_attr "type" "branch") (set_attr "cc" "clobber")])(define_insn "bcs_hihi" [(set (pc) (if_then_else (match_operator 1 "eq_operator" [(zero_extract:HI (match_operand:HI 2 "bit_operand" "Ur") (const_int 1) (match_operand:HI 3 "immediate_operand" "i")) (const_int 0)]) (label_ref (match_operand 0 "" "")) (pc)))] "" "*{ output_asm_insn(\"bld %Z3,%Y2\", operands); if (get_attr_length (insn) == 2) return \"%d1 %l0\"; else if (get_attr_length (insn) == 4) return \"%d1 %l0:16\"; else return \"%g1 %L0\;jmp @%l0\;%L0:\";}" [(set_attr "type" "branch") (set_attr "cc" "clobber")])(define_insn "bcs_hiqi" [(set (pc) (if_then_else (match_operator 1 "eq_operator" [(zero_extract:HI (match_operand:QI 2 "bit_operand" "Ur") (const_int 1) (match_operand:HI 3 "immediate_operand" "i")) (const_int 0)]) (label_ref (match_operand 0 "" "")) (pc)))] "" "*{ output_asm_insn(\"bld %Z3,%Y2\", operands); if (get_attr_length (insn) == 2) return \"%d1 %l0\"; else if (get_attr_length (insn) == 4) return \"%d1 %l0:16\"; else return \"%g1 %L0\;jmp @%l0\;%L0:\";}" [(set_attr "type" "branch") (set_attr "cc" "clobber")]);; BLD and BST patterns(define_insn "extract_1" [(set (match_operand:HI 0 "register_operand" "=&r") (zero_extract:HI (match_operand:QI 1 "bit_operand" "Ur") (const_int 1) (match_operand:HI 2 "immediate_operand" "i")))] "" "sub.w %0,%0\;bld %Z2,%Y1\;bst #0,%X0")(define_insn "extract_1_hi" [(set (match_operand:HI 0 "register_operand" "=&r") (zero_extract:HI (match_operand:HI 1 "bit_operand" "Ur") (const_int 1) (match_operand:HI 2 "immediate_operand" "i")))] "" "sub.w %0,%0\;bld %Z2,%Y1\;bst #0,%X0")(define_insn "insert_1" [(set (zero_extract:HI (match_operand:QI 0 "bit_operand" "+Ur") (const_int 1) (match_operand:HI 1 "immediate_operand" "i")) (zero_extract:HI (match_operand:QI 2 "bit_operand" "Ur") (const_int 1) (const_int 0)))] "" "bld #0,%X2\;bst %Z1,%Y0 ; i1");; This is how combine canonicalizes this pattern. This is perhaps a bug;; in combine.c, but there is no problem with writing it this way so we do.(define_insn "extract_insert_1" [(set (zero_extract:QI (match_operand:QI 0 "bit_operand" "+Ur") (const_int 1) (match_operand:HI 1 "immediate_operand" "i")) (lshiftrt:QI (match_operand:QI 2 "bit_operand" "Ur") (match_operand:HI 3 "immediate_operand" "i")))] "" "bld %Z3,%Y2\;bst %Z1,%Y0; ei1");; BAND, BOR, and BXOR patterns(define_insn "bitlogical_1" [(set (match_operand:HI 0 "bit_operand" "=Ur") (match_operator:HI 4 "bit_operator" [(zero_extract:HI (match_operand:QI 1 "bit_operand" "Ur") (const_int 1) (match_operand:HI 2 "immediate_operand" "i")) (match_operand:HI 3 "bit_operand" "0")]))] "" "bld %Z2,%Y1\;%b4 #0,%X0\;bst #0,%X0; bl1")(define_insn "bitlogical_1_hi" [(set (match_operand:HI 0 "bit_operand" "=Ur") (match_operator:HI 4 "bit_operator" [(zero_extract:HI (match_operand:HI 1 "bit_operand" "Ur") (const_int 1) (match_operand:HI 2 "immediate_operand" "i")) (match_operand:HI 3 "bit_operand" "0")]))] ""
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -