📄 h8300.md
字号:
"bld %Z2,%Y1\;%b4 #0,%X0\;bst #0,%X0; bl2")(define_insn "bitlogical_2" [(set (match_operand:HI 0 "bit_operand" "=Ur") (match_operator:HI 5 "bit_operator" [(zero_extract:HI (match_operand:QI 1 "bit_operand" "Ur") (const_int 1) (match_operand:HI 2 "immediate_operand" "i")) (zero_extract:HI (match_operand:QI 3 "bit_operand" "Ur") (const_int 1) (match_operand:HI 4 "immediate_operand" "i"))]))] "" "bld %Z2,%Y1\;%b5 %Z4,%Y3\;bst #0,%X0; bl3")(define_insn "bitlogical_2_hi" [(set (match_operand:HI 0 "bit_operand" "=Ur") (match_operator:HI 5 "bit_operator" [(zero_extract:HI (match_operand:HI 1 "bit_operand" "Ur") (const_int 1) (match_operand:HI 2 "immediate_operand" "i")) (zero_extract:HI (match_operand:HI 3 "bit_operand" "Ur") (const_int 1) (match_operand:HI 4 "immediate_operand" "i"))]))] "" "bld %Z2,%Y1\;%b5 %Z4,%Y3\;bst #0,%X0; bl3");; 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 "bitlogical_3" [(set (zero_extract:QI (match_operand:QI 0 "bit_operand" "+Ur") (const_int 1) (match_operand:HI 1 "immediate_operand" "i")) (match_operator:QI 6 "bit_operator" [(lshiftrt:QI (match_operand:QI 2 "bit_operand" "Ur") (match_operand:HI 3 "immediate_operand" "i")) (lshiftrt:QI (match_operand:QI 4 "bit_operand" "Ur") (match_operand:HI 5 "immediate_operand" "i"))]))] "" "bld %Z3,%Y2\;%b6 %Z5,%Y4\;bst %Z1,%Y0; bl5") ;; 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 "bitnot_1" [(set (zero_extract:QI (match_operand:QI 0 "bit_operand" "=Ur") (const_int 1) (match_operand:HI 1 "immediate_operand" "i")) (lshiftrt:QI (xor:QI (match_operand:QI 2 "bit_operand" "0") (match_operand:HI 3 "immediate_operand" "i")) (match_operand:HI 4 "immediate_operand" "1")))] "GET_CODE (operands[3]) == CONST_INT && GET_CODE (operands[1]) == CONST_INT && exact_log2 (INTVAL (operands[3])) == INTVAL (operands[1])" "bnot %Z1,%Y0");; ??? Implement BIAND, BIOR, BIXOR;; ??? Implement BILD, BIST;; ??? Apparently general_operand for the 1st and 2nd operands is useful,;; but I don't know why. --Jim(define_expand "insv" [(set (zero_extract:HI (match_operand:QI 0 "bit_operand" "Ur") (match_operand:HI 1 "general_operand" "g") (match_operand:HI 2 "general_operand" "g")) (zero_extract:HI (match_operand:QI 3 "bit_operand" "Ur") (const_int 1) (const_int 0)))];; ??? This should have word mode which is SImode for the h8/300h. "TARGET_H8300" "{ if (INTVAL (operands[1]) != 1) FAIL; /* ??? HACK ??? This INSV pattern is wrong. It should use HImode for operand 3. Also, the zero_extract around operand 3 is superfluous and should be deleted. Fixing this is more work than we care to do for the moment, because it means most of the above patterns would need to be rewritten, and we also need more combine.c patches to make this work. So, for now, we work around this bug by simply not accepting any bitfield inserts that have a position greater than fits in QImode. */ if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) >= 8) FAIL; /* The bit_operand predicate accepts any memory during RTL generation, but only 'U' memory afterwards, so if this is a MEM operand, we must force it to be valid for 'U' by reloading the address. */ if (GET_CODE (operands[0]) == MEM && ! EXTRA_CONSTRAINT (operands[0], 'U')) { rtx mem; mem = gen_rtx (MEM, GET_MODE (operands[0]), copy_to_mode_reg (Pmode, XEXP (operands[0], 0))); RTX_UNCHANGING_P (mem) = RTX_UNCHANGING_P (operands[0]); MEM_IN_STRUCT_P (mem) = MEM_IN_STRUCT_P (operands[0]); MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[0]); operands[0] = mem; } /* Likewise for operands[3]. */ if (GET_CODE (operands[3]) == MEM && ! EXTRA_CONSTRAINT (operands[3], 'U')) { rtx mem; mem = gen_rtx (MEM, GET_MODE (operands[3]), copy_to_mode_reg (Pmode, XEXP (operands[3], 0))); RTX_UNCHANGING_P (mem) = RTX_UNCHANGING_P (operands[3]); MEM_IN_STRUCT_P (mem) = MEM_IN_STRUCT_P (operands[3]); MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[3]); operands[3] = mem; }}");; ??? Apparently general_operand for the 2nd and 3rd operands is useful,;; but I don't know why. --Jim(define_expand "extzv" [(set (match_operand:HI 0 "register_operand" "") (zero_extract:HI (match_operand:QI 1 "bit_operand" "") (match_operand:HI 2 "general_operand" "g") (match_operand:HI 3 "general_operand" "g")))];; ??? This should have word mode which is SImode for the h8/300h. "TARGET_H8300" "{ if (INTVAL (operands[2]) != 1) FAIL; /* The bit_operand predicate accepts any memory during RTL generation, but only 'U' memory afterwards, so if this is a MEM operand, we must force it to be valid for 'U' by reloading the address. */ if (GET_CODE (operands[1]) == MEM && ! EXTRA_CONSTRAINT (operands[1], 'U')) { rtx mem; mem = gen_rtx (MEM, GET_MODE (operands[1]), copy_to_mode_reg (Pmode, XEXP (operands[1], 0))); RTX_UNCHANGING_P (mem) = RTX_UNCHANGING_P (operands[1]); MEM_IN_STRUCT_P (mem) = MEM_IN_STRUCT_P (operands[1]); MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (operands[1]); operands[1] = mem; }}");; -----------------------------------------------------------------;; STACK POINTER MANIPULATIONS;; -----------------------------------------------------------------;; This pattern is needed because there is no way on the H8/300;; to add a 16 bit immediate value to the stack pointer in one ;; instruction, which could leave an invalid instruction if interrupted;; half way through. Here we add to the stack pointer from a;; register.(define_insn "stack_pointer_manip" [(set (match_operand:HI 0 "register_operand" "=&ra") (plus:HI (match_operand:HI 1 "general_operand_src" "g") (match_operand:HI 2 "register_operand" "ra")))] "TARGET_H8300" "mov.w %T1,%T0\;add.w %T2,%T0" [(set_attr "type" "arith") (set_attr "length" "6") (set_attr "cc" "set")]);; -------------------------------------------;; BLK moves;; -------------------------------------------(define_expand "movstrhi" [(parallel [(set (mem:BLK (match_operand:BLK 0 "general_operand" "")) (mem:BLK (match_operand:BLK 1 "general_operand" ""))) (use (match_operand:HI 2 "general_operand" "")) (use (match_operand:HI 3 "immediate_operand" "")) (clobber (match_dup 3)) ])] "" "{ rtx src_ptr = copy_to_mode_reg (Pmode, XEXP(operands[1], 0)); rtx dst_ptr = copy_to_mode_reg (Pmode, XEXP(operands[0], 0)); int max = GET_CODE (operands[2]) == CONST_INT ? MIN (INTVAL (operands[2]), INTVAL (operands[3])) : 1; enum machine_mode mode = max >= 2 ? HImode : QImode; rtx tmpreg = gen_reg_rtx (mode); rtx increment = mode == QImode ? const1_rtx : const2_rtx; rtx length = operands[2]; rtx label = gen_label_rtx (); rtx end_src_ptr = gen_reg_rtx (Pmode);/* emit_move_insn (length, gen_rtx(MINUS, HImode, length, increment));*/ FAIL; if (Pmode == HImode) emit_insn (gen_addhi3 (end_src_ptr, src_ptr, length)); else emit_insn (gen_addsi3 (end_src_ptr, src_ptr, length)); emit_label (label); emit_move_insn (tmpreg, gen_rtx (MEM, mode, src_ptr)); emit_move_insn (gen_rtx (MEM, mode, dst_ptr), tmpreg); emit_insn (gen_rtx (SET, VOIDmode, src_ptr, gen_rtx (PLUS, Pmode, src_ptr, increment))); emit_insn (gen_rtx (SET, VOIDmode, dst_ptr, gen_rtx (PLUS, Pmode, dst_ptr, increment))); emit_insn (gen_rtx (SET, VOIDmode, cc0_rtx, gen_rtx (COMPARE, Pmode, src_ptr, end_src_ptr))); emit_jump_insn (gen_bne (label)); DONE; }");; ----------------------------------------------;; Peepholes go at the end.;; ----------------------------------------------;; Notice when two byte moves in a row could be a word move.(define_peephole [(set (match_operand:QI 0 "register_operand" "=r") (mem:QI (plus:HI (match_operand:HI 1 "register_operand" "ra") (match_operand:HI 2 "immediate_operand" "n")))) (set (match_operand:QI 3 "register_operand" "=r") (mem:QI (plus:HI (match_dup 1) (match_operand:HI 4 "immediate_operand" "n"))))] "(INTVAL(operands[2]) == INTVAL(operands[4])+1) && REGNO(operands[0]) +1 == REGNO(operands[3])" "mov.w @(%u4,%T1),%T0" [(set_attr "length" "6") (set_attr "cc" "set")])(define_peephole [(set (mem:QI (plus:HI (match_operand:HI 1 "register_operand" "ra") (match_operand:HI 2 "immediate_operand" "n"))) (match_operand:QI 0 "register_operand" "r")) (set (mem:QI (plus:HI (match_dup 1) (match_operand:HI 4 "immediate_operand" "n"))) (match_operand:QI 3 "register_operand" "r"))] "(INTVAL(operands[2]) == INTVAL(operands[4])+1) && REGNO(operands[0]) +1 == REGNO(operands[3])" "mov.w %T0,@(%u4,%T1)" [(set_attr "length" "6") (set_attr "cc" "set")]);; Notice a move which could be post incremented.(define_peephole [(set (match_operand:QI 0 "register_operand" "") (mem:QI (match_operand:HI 1 "register_operand" ""))) (set (match_dup 1) (plus:HI (match_dup 1) (const_int 1)))] "REGNO(operands[1]) != REGNO(operands[0])" "mov.b @%T1+,%X0" [(set_attr "length" "2") (set_attr "cc" "set")])(define_peephole [(set (match_operand:HI 0 "register_operand" "") (mem:HI (match_operand:HI 1 "register_operand" ""))) (set (match_dup 1) (plus:HI (match_dup 1) (const_int 2)))] "REGNO(operands[1]) != REGNO(operands[0])" "mov.w @%T1+,%T0" [(set_attr "length" "2") (set_attr "cc" "set")]);; Notice a move which could be predecremented.(define_peephole [(set (match_operand:HI 1 "register_operand" "") (plus:HI (match_dup 1) (const_int -1))) (set (mem:QI (match_dup 1)) (match_operand:QI 0 "register_operand" ""))] "REGNO(operands[1]) != REGNO(operands[0])" "mov.b %X0,@-%T1" [(set_attr "length" "2") (set_attr "cc" "set")])(define_peephole [(set (match_operand:HI 1 "register_operand" "") (plus:HI (match_dup 1) (const_int -1))) (set (mem:HI (match_dup 1)) (match_operand:HI 0 "register_operand" ""))] "REGNO(operands[1]) != REGNO(operands[0])" "mov.w %T0,@-%T1" [(set_attr "length" "2") (set_attr "cc" "set")]);(define_insn ""; [(set (match_operand:HI 0 "register_operand" "=r"); (MEM:HI (match_operand:HI 1 "register_operand" "r"))); (set (match_operand:HI 3 "register_operand" "=r"); (zero_extract:HI (match_dup 0); (const_int 1); (match_operand:HI 2 "general_operand" "g"))); (set (MEM:HI (match_dup 1) (match_dup 3)))]; ""; "bld #0,%3l\;bst %Z2,%0%Y1"; [(set_attr "type" "multi"); (set_attr "length" "4"); (set_attr "cc" "clobber")])(define_insn "fancybset1" [(set (match_operand:QI 0 "bit_operand" "=Ur") (ior:QI (subreg:QI (ashift:HI (const_int 1) (subreg:QI (match_operand:HI 1 "register_operand" "ri") 0)) 0) (match_dup 0)))] "" "bset %X1,%X0") (define_insn "fancybset" [(set (match_operand:QI 0 "bit_operand" "=Ur") (ior:QI (subreg:QI (ashift:HI (const_int 1) (match_operand:HI 1 "nonmemory_operand" "ri") ) 0) (match_operand:QI 2 "general_operand" "Ur")))] "" "mov.b %X2,%X0\;bset %X1,%X0") (define_insn "fancybclr4" [(set (match_operand:QI 0 "general_operand" "=Ur,Ur") (and:QI (subreg:QI (rotate:HI (const_int -2) (match_operand:HI 2 "nonmemory_operand" "ri,ri") ) 0) (match_operand:QI 1 "general_operand" "0,Ur"))) (clobber (match_scratch:HI 3 "=X,&r"))] "" "@ bclr %X2,%X0; l1 mov.b %X1,%X3\;mov.b %3,%0\;bclr %X2,%X0; l3")(define_insn "fancybclr5" [(set (match_operand:QI 0 "general_operand" "=Ur,Ur") (and:QI (subreg:QI (rotate:HI (const_int -2) (match_operand:QI 2 "nonmemory_operand" "ri,ri")) 0) (match_operand:QI 1 "general_operand" "0,Ur"))) (clobber (match_scratch:HI 3 "=X,&r"))] "" "@ bclr %X2,%X0; l1 mov.b %X1,%X3\;mov.b %3,%0\;bclr %X2,%X0;l2")(define_insn "fancybclr2" [(set (match_operand:QI 0 "general_operand" "=U,r") (and:QI (subreg:QI (rotate:HI (const_int -2) (match_operand:HI 2 "nonmemory_operand" "ri,ri") ) 0) (match_operand:QI 1 "general_operand" "0,0")))] "" "bclr %X2,%X0")(define_insn "fancybclr3" [(set (match_operand:QI 0 "general_operand" "=U,r") (and:QI (subreg:QI (rotate:HI (const_int -2) (match_operand:QI 2 "nonmemory_operand" "ri,ri")) 0) (match_operand:QI 1 "general_operand" "0,0")))] "" "bclr %X2,%X0")(define_insn "fancybclr" [(set (match_operand:QI 0 "general_operand" "=r") (and:QI (not:QI (match_operand:QI 1 "general_operand" "0")) (match_operand:QI 2 "general_operand" "r")))] "" "not %X0\;and %X2,%X0")(define_insn "fancybsetp3" [(set (match_operand:QI 0 "bit_operand" "=Ur") (ior:QI (subreg:QI (ashift:HI (const_int 1) (match_operand:QI 1 "register_operand" "r")) 0) (match_operand:QI 2 "bit_operand" "0")))] "" "bset %X1,%X0")(define_insn "fancybsetp2" [(set (match_operand:QI 0 "general_operand" "=r,U") (ior:QI (subreg:QI (ashift:HI (const_int 1) (match_operand:QI 1 "register_operand" "r,r")) 0) (match_operand:QI 2 "general_operand" "U,r")))] "" "mov.b %X2,%X0\;bset %X1,%X0") (define_insn "fancybnot" [(set (match_operand:QI 0 "bit_operand" "=Ur") (xor:QI (subreg:QI (ashift:HI (const_int 1) (match_operand:QI 1 "register_operand" "r")) 0) (match_operand:QI 2 "bit_operand" "0")))] "" "bnot %X1,%X0")(define_insn "fancy_btst" [(set (pc) (if_then_else (eq (zero_extract:HI (zero_extend:HI (match_operand:QI 1 "general_operand" "Ur")) (const_int 1) (match_operand:HI 2 "nonmemory_operand" "rn")) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "*{ if (get_attr_length (insn) == 2) return \"btst %X2,%X1\;beq %l0\"; else if (get_attr_length (insn) == 4) return \"btst %X2,%X1\;beq %l0:16\"; else return \"btst %X2,%X1\;bne %L1\;jmp @%l0\;%L1:\";}" [(set_attr "type" "branch") (set_attr "cc" "clobber")])(define_insn "fancy_btst1" [(set (pc) (if_then_else (ne (zero_extract:HI (zero_extend:HI (match_operand:QI 1 "general_operand" "Ur")) (const_int 1) (match_operand:HI 2 "nonmemory_operand" "rn")) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "*{ if (get_attr_length (insn) == 2) return \"btst %X2,%X1\;bne %l0\"; else if (get_attr_length (insn) == 4) return \"btst %X2,%X1\;bne %l0:16\"; else return \"btst %X2,%X1\;beq %L1\;jmp @%l0\;%L1:\";}" [(set
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -