📄 vax.md
字号:
(label_ref (match_operand 0 "" "")) (pc)))] "" "jeql %l0")(define_insn "bne" [(set (pc) (if_then_else (ne (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "jneq %l0")(define_insn "bgt" [(set (pc) (if_then_else (gt (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "jgtr %l0")(define_insn "bgtu" [(set (pc) (if_then_else (gtu (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "jgtru %l0")(define_insn "blt" [(set (pc) (if_then_else (lt (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "jlss %l0")(define_insn "bltu" [(set (pc) (if_then_else (ltu (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "jlssu %l0")(define_insn "bge" [(set (pc) (if_then_else (ge (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "jgeq %l0")(define_insn "bgeu" [(set (pc) (if_then_else (geu (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "jgequ %l0")(define_insn "ble" [(set (pc) (if_then_else (le (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "jleq %l0")(define_insn "bleu" [(set (pc) (if_then_else (leu (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "jlequ %l0");; Recognize reversed jumps.(define_insn "" [(set (pc) (if_then_else (match_operator 0 "comparison_operator" [(cc0) (const_int 0)]) (pc) (label_ref (match_operand 1 "" ""))))] "" "j%C0 %l1") ; %C0 negates condition;; Recognize jbs, jlbs, jbc and jlbc instructions. Note that the operand;; of jlbs and jlbc insns are SImode in the hardware. However, if it is;; memory, we use QImode in the insn. So we can't use those instructions;; for mode-dependent addresses.(define_insn "" [(set (pc) (if_then_else (ne (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "rQ,g") (const_int 1) (match_operand:SI 1 "general_operand" "I,g")) (const_int 0)) (label_ref (match_operand 2 "" "")) (pc)))] "" "@ jlbs %0,%l2 jbs %1,%0,%l2")(define_insn "" [(set (pc) (if_then_else (eq (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "rQ,g") (const_int 1) (match_operand:SI 1 "general_operand" "I,g")) (const_int 0)) (label_ref (match_operand 2 "" "")) (pc)))] "" "@ jlbc %0,%l2 jbc %1,%0,%l2")(define_insn "" [(set (pc) (if_then_else (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r,r") (const_int 1) (match_operand:SI 1 "general_operand" "I,g")) (const_int 0)) (label_ref (match_operand 2 "" "")) (pc)))] "" "@ jlbs %0,%l2 jbs %1,%0,%l2")(define_insn "" [(set (pc) (if_then_else (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r,r") (const_int 1) (match_operand:SI 1 "general_operand" "I,g")) (const_int 0)) (label_ref (match_operand 2 "" "")) (pc)))] "" "@ jlbc %0,%l2 jbc %1,%0,%l2");; Subtract-and-jump and Add-and-jump insns.;; These are not used when output is for the Unix assembler;; because it does not know how to modify them to reach far.;; Normal sob insns.(define_insn "" [(set (pc) (if_then_else (gt (plus:SI (match_operand:SI 0 "general_operand" "+g") (const_int -1)) (const_int 0)) (label_ref (match_operand 1 "" "")) (pc))) (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))] "!TARGET_UNIX_ASM" "jsobgtr %0,%l1")(define_insn "" [(set (pc) (if_then_else (ge (plus:SI (match_operand:SI 0 "general_operand" "+g") (const_int -1)) (const_int 0)) (label_ref (match_operand 1 "" "")) (pc))) (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))] "!TARGET_UNIX_ASM" "jsobgeq %0,%l1");; Normal aob insns. Define a version for when operands[1] is a constant.(define_insn "" [(set (pc) (if_then_else (lt (plus:SI (match_operand:SI 0 "general_operand" "+g") (const_int 1)) (match_operand:SI 1 "general_operand" "g")) (label_ref (match_operand 2 "" "")) (pc))) (set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))] "!TARGET_UNIX_ASM" "jaoblss %1,%0,%l2")(define_insn "" [(set (pc) (if_then_else (lt (match_operand:SI 0 "general_operand" "+g") (match_operand:SI 1 "general_operand" "g")) (label_ref (match_operand 2 "" "")) (pc))) (set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))] "!TARGET_UNIX_ASM && GET_CODE (operands[1]) == CONST_INT" "jaoblss %P1,%0,%l2")(define_insn "" [(set (pc) (if_then_else (le (plus:SI (match_operand:SI 0 "general_operand" "+g") (const_int 1)) (match_operand:SI 1 "general_operand" "g")) (label_ref (match_operand 2 "" "")) (pc))) (set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))] "!TARGET_UNIX_ASM" "jaobleq %1,%0,%l2")(define_insn "" [(set (pc) (if_then_else (le (match_operand:SI 0 "general_operand" "+g") (match_operand:SI 1 "general_operand" "g")) (label_ref (match_operand 2 "" "")) (pc))) (set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))] "!TARGET_UNIX_ASM && GET_CODE (operands[1]) == CONST_INT" "jaobleq %P1,%0,%l2");; Something like a sob insn, but compares against -1.;; This finds `while (foo--)' which was changed to `while (--foo != -1)'.(define_insn "" [(set (pc) (if_then_else (ne (match_operand:SI 0 "general_operand" "g") (const_int 0)) (label_ref (match_operand 1 "" "")) (pc))) (set (match_dup 0) (plus:SI (match_dup 0) (const_int -1)))] "" "decl %0\;jgequ %l1");; Note that operand 1 is total size of args, in bytes,;; and what the call insn wants is the number of words.(define_insn "call_pop" [(call (match_operand:QI 0 "memory_operand" "m") (match_operand:QI 1 "general_operand" "g")) (set (reg:SI 14) (plus:SI (reg:SI 14) (match_operand:SI 3 "immediate_operand" "i")))] "" "* if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) > 255 * 4) /* Vax `calls' really uses only one byte of #args, so pop explicitly. */ return \"calls $0,%0\;addl2 %1,sp\"; operands[1] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[1]) + 3)/ 4); return \"calls %1,%0\";")(define_insn "call_value_pop" [(set (match_operand 0 "" "=g") (call (match_operand:QI 1 "memory_operand" "m") (match_operand:QI 2 "general_operand" "g"))) (set (reg:SI 14) (plus:SI (reg:SI 14) (match_operand:SI 4 "immediate_operand" "i")))] "" "* if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) > 255 * 4) /* Vax `calls' really uses only one byte of #args, so pop explicitly. */ return \"calls $0,%1\;addl2 %2,sp\"; operands[2] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[2]) + 3)/ 4); return \"calls %2,%1\";");; Define another set of these for the case of functions with no;; operands. In that case, combine may simplify the adjustment of sp.(define_insn "" [(call (match_operand:QI 0 "memory_operand" "m") (match_operand:QI 1 "general_operand" "g")) (set (reg:SI 14) (reg:SI 14))] "" "* if (GET_CODE (operands[1]) != CONST_INT || INTVAL (operands[1]) > 255 * 4) /* Vax `calls' really uses only one byte of #args, so pop explicitly. */ return \"calls $0,%0\;addl2 %1,sp\"; operands[1] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[1]) + 3)/ 4); return \"calls %1,%0\";")(define_insn "" [(set (match_operand 0 "" "=g") (call (match_operand:QI 1 "memory_operand" "m") (match_operand:QI 2 "general_operand" "g"))) (set (reg:SI 14) (reg:SI 14))] "" "* if (GET_CODE (operands[2]) != CONST_INT || INTVAL (operands[2]) > 255 * 4) /* Vax `calls' really uses only one byte of #args, so pop explicitly. */ return \"calls $0,%1\;addl2 %2,sp\"; operands[2] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[2]) + 3)/ 4); return \"calls %2,%1\";")(define_insn "return" [(return)] "" "ret")(define_insn "nop" [(const_int 0)] "" "nop");; This had a wider constraint once, and it had trouble.;; If you are tempted to try `g', please don't--it's not worth;; the risk we will reopen the same bug.(define_insn "indirect_jump" [(set (pc) (match_operand:SI 0 "general_operand" "r"))] "" "jmp (%0)");; This is here to accept 5 arguments (as passed by expand_end_case);; and pass the first 4 along to the casesi1 pattern that really does the work.(define_expand "casesi" [(set (pc) (if_then_else (leu (minus:SI (match_operand:SI 0 "general_operand" "g") (match_operand:SI 1 "general_operand" "g")) (match_operand:SI 2 "general_operand" "g")) (plus:SI (sign_extend:SI (mem:HI (plus:SI (pc) (mult:SI (minus:SI (match_dup 0) (match_dup 1)) (const_int 2))))) (label_ref:SI (match_operand 3 "" ""))) (pc))) (match_operand 4 "" "")] "" " emit_insn (gen_casesi1 (operands[0], operands[1], operands[2], operands[3])); DONE;")(define_insn "casesi1" [(set (pc) (if_then_else (leu (minus:SI (match_operand:SI 0 "general_operand" "g") (match_operand:SI 1 "general_operand" "g")) (match_operand:SI 2 "general_operand" "g")) (plus:SI (sign_extend:SI (mem:HI (plus:SI (pc) (mult:SI (minus:SI (match_dup 0) (match_dup 1)) (const_int 2))))) (label_ref:SI (match_operand 3 "" ""))) (pc)))] "" "casel %0,%1,%2");; This used to arise from the preceding by simplification;; if operand 1 is zero. Perhaps it is no longer necessary.(define_insn "" [(set (pc) (if_then_else (leu (match_operand:SI 0 "general_operand" "g") (match_operand:SI 1 "general_operand" "g")) (plus:SI (sign_extend:SI (mem:HI (plus:SI (pc) (mult:SI (minus:SI (match_dup 0) (const_int 0)) (const_int 2))))) (label_ref:SI (match_operand 3 "" ""))) (pc)))] "" "casel %0,$0,%1");;- load or push effective address ;; These come after the move and add/sub patterns;; because we don't want pushl $1 turned into pushad 1.;; or addl3 r1,r2,r3 turned into movab 0(r1)[r2],r3.(define_insn "" [(set (match_operand:SI 0 "general_operand" "=<,g") (match_operand:QI 1 "address_operand" "p,p"))] "" "@ pushab %a1 movab %a1,%0")(define_insn "" [(set (match_operand:SI 0 "general_operand" "=<,g") (match_operand:HI 1 "address_operand" "p,p"))] "" "@ pushaw %a1 movaw %a1,%0")(define_insn "" [(set (match_operand:SI 0 "general_operand" "=<,g") (match_operand:SI 1 "address_operand" "p,p"))] "" "@ pushal %a1 moval %a1,%0")(define_insn "" [(set (match_operand:SI 0 "general_operand" "=<,g") (match_operand:DI 1 "address_operand" "p,p"))] "" "@ pushaq %a1 movaq %a1,%0")(define_insn "" [(set (match_operand:SI 0 "general_operand" "=<,g") (match_operand:SF 1 "address_operand" "p,p"))] "" "@ pushaf %a1 movaf %a1,%0")(define_insn "" [(set (match_operand:SI 0 "general_operand" "=<,g") (match_operand:DF 1 "address_operand" "p,p"))] "" "@ pushad %a1 movad %a1,%0");; These used to be peepholes, but it is more straightforward to do them;; as single insns. However, we must force the output to be a register;; if it is not an offsettable address so that we know that we can assign;; to it twice. ;; If we had a good way of evaluating the relative costs, these could be;; machine-independent.;; Optimize extzv ...,z; andl2 ...,z;; or ashl ...,z; andl2 ...,z;; with other operands constant. This is what the combiner converts the;; above sequences to before attempting to recognize the new insn.(define_insn "" [(set (match_operand:SI 0 "general_operand" "=ro") (and:SI (ashiftrt:SI (match_operand:SI 1 "general_operand" "g") (match_operand:QI 2 "const_int_operand" "n")) (match_operand:SI 3 "const_int_operand" "n")))] "(INTVAL (operands[3]) & ~((1 << (32 - INTVAL (operands[2]))) - 1)) == 0" "*{ unsigned long mask1 = INTVAL (operands[3]); unsigned long mask2 = (1 << (32 - INTVAL (operands[2]))) - 1; if ((mask1 & mask2) != mask1) operands[3] = gen_rtx (CONST_INT, VOIDmode, mask1 & mask2); return \"rotl %R2,%1,%0\;bicl2 %N3,%0\";}");; left-shift and mask;; The only case where `ashl' is better is if the mask only turns off;; bits that the ashl would anyways, in which case it should have been;; optimized away.(define_insn "" [(set (match_operand:SI 0 "general_operand" "=ro") (and:SI (ashift:SI (match_operand:SI 1 "general_operand" "g") (match_operand:QI 2 "const_int_operand" "n")) (match_operand:SI 3 "const_int_operand" "n")))] "" "*{ operands[3] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[3]) & ~((1 << INTVAL (operands[2])) - 1)); return \"rotl %2,%1,%0\;bicl2 %N3,%0\";}");;- Local variables:;;- mode:emacs-lisp;;- comment-start: ";;- ";;- eval: (set-syntax-table (copy-sequence (syntax-table)));;- eval: (modify-syntax-entry ?[ "(]");;- eval: (modify-syntax-entry ?] ")[");;- eval: (modify-syntax-entry ?{ "(}");;- eval: (modify-syntax-entry ?} "){");;- End:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -