📄 gmicro.md
字号:
(define_insn "" [(set (match_operand:SI 0 "general_operand" "=r") (sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro") (match_operand:SI 2 "immediate_operand" "i") (match_operand:SI 3 "immediate_operand" "i")))] "TARGET_BITFIELD && GET_CODE (operands[2]) == CONST_INT && (INTVAL (operands[2]) == 8 || INTVAL (operands[2]) == 16) && GET_CODE (operands[3]) == CONST_INT && INTVAL (operands[3]) % INTVAL (operands[2]) == 0" "*{ if (!REG_P (operands[1])) operands[1] = adj_offsettable_operand (operands[1], INTVAL (operands[3]) / 8); if (REG_P (operands[0])) { if (REG_P (operands[1])) { if (INTVAL (operands[2]) == 8) { /* width == 8 */ switch (INTVAL (operands[3])) { case 0: return \"mov.w %1,%0;sha.w #-24,%0\"; break; case 8: return \"mov.w %1,%0;shl.w #8,%0;sha.w #-24,%0\"; break; case 16: return \"mov.w %1,%0;shl.w #16,%0;sha.w #-24,%0\"; break; case 24: return \"mov %1.b,%0.w\"; break; default: myabort (4); } } else { switch (INTVAL (operands[3])) { case 0: return \"mov.w %1,%0;sha.w #-16,%0\"; break; case 16: return \"mov %1.h,%0.w\"; break; default: myabort (5); } } } else { if (INTVAL (operands[2]) == 8) return \"mov %1.h,%0.w\"; else return \"mov %1.b,%0.w\"; } } else { /* op[0] == MEM */ if (INTVAL (operands[2]) == 8) return \"mov %1.b,%0.w\"; return \"mov %1.h,%0.w\"; }}");; Bit field instructions, general cases.;; "o,d" constraint causes a nonoffsettable memref to match the "o";; so that its address is reloaded.;; extv dest:SI src(:QI/:SI) width:SI pos:SI;; r.w m r.w/# rmi ;; %0 %1 %2 %3(define_insn "extv" [(set (match_operand:SI 0 "general_operand" "=r") (sign_extract:SI (match_operand:QI 1 "nonimmediate_operand" "m") (match_operand:SI 2 "general_operand" "ri") (match_operand:SI 3 "general_operand" "rmi")))] "TARGET_BITFIELD" "bfext %3,%2,%1,%0")(define_insn "extzv" [(set (match_operand:SI 0 "general_operand" "=r") (zero_extract:SI (match_operand:QI 1 "nonimmediate_operand" "m") (match_operand:SI 2 "general_operand" "ri") (match_operand:SI 3 "general_operand" "rmi")))] "TARGET_BITFIELD" "bfextu %3,%2,%1,%0");; There is no insn on the Gmicro to NOT/SET/CLR bitfield.;; insv dest(BF):QI/SI width:SI pos:SI src:SI;; m r.w rmi r.w/i;; 0 1 2 3(define_insn "insv" [(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+m,m") (match_operand:SI 1 "general_operand" "r,i") (match_operand:SI 2 "general_operand" "rmi,i")) (match_operand:SI 3 "general_operand" "ri,ri"))] "TARGET_BITFIELD" "bfinsu %3,%2,%1,%0");;; bfins/bfinsu ????????;; == == == == == == == == == == == == == ;; Now recognize bit field insns that operate on registers;; (or at least were intended to do so).;; On the Gmicro/300,;; bitfield instructions are not applicable to registers ;-<;; But I write the register cases, because without them the gcc;; seems to use "and" instruction with some other instructions;; instead of using a shift instruction.;; It is because on many processors shift instructions are slower.;; On the Gmicro/300 which has a barrel shifter,;; it is faster to use a shift instruction.;;;; Restricts width and offset to be immediates.;;(define_insn "" [(set (match_operand:SI 0 "general_operand" "=r") (sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "r") (match_operand:SI 2 "immediate_operand" "i") (match_operand:SI 3 "immediate_operand" "i")))] "TARGET_BITFIELD" "*{ if (REGNO (operands[0]) != REGNO (operands[1])) output_asm_insn (\"mov.w %1,%0\", operands); if (INTVAL (operands[3]) != 0) output_asm_insn (\"shl.w %3,%0\", operands); operands[2] = gen_rtx (CONST_INT, VOIDmode, -(32 - INTVAL (operands[2]))); return \"sha.w %3,%0\";}") (define_insn "" [(set (match_operand:SI 0 "general_operand" "=r") (zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "r") (match_operand:SI 2 "immediate_operand" "i") (match_operand:SI 3 "immediate_operand" "i")))] "TARGET_BITFIELD" "*{ if (REGNO (operands[0]) != REGNO (operands[1])) output_asm_insn (\"mov.w %1,%0\", operands); if (INTVAL (operands[3]) != 0) output_asm_insn (\"shl.w %3,%0\", operands); operands[2] = gen_rtx (CONST_INT, VOIDmode, -(32 - INTVAL (operands[2]))); return \"shl.w %3,%0\";}");; There are more descriptions for m68k, but not yet for the Gmicro.;;;; Basic conditional jump instructions.(define_insn "beq" [(set (pc) (if_then_else (eq (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "*{ OUTPUT_JUMP (\"beq %b0\", \"fbeq %b0\", \"beq %b0\");}")(define_insn "bne" [(set (pc) (if_then_else (ne (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "*{ OUTPUT_JUMP (\"bne %b0\", \"fbne %b0\", \"bne %b0\");}")(define_insn "bgt" [(set (pc) (if_then_else (gt (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "* OUTPUT_JUMP (\"bgt %b0\", \"fbgt %b0\", 0);")(define_insn "bgtu" [(set (pc) (if_then_else (gtu (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "bgt %b0")(define_insn "blt" [(set (pc) (if_then_else (lt (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "* OUTPUT_JUMP (\"blt %b0\", \"fblt %b0\", \"bms %b0\");");; bms ?????;; (define_insn "bltu" [(set (pc) (if_then_else (ltu (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "blt %b0")(define_insn "bge" [(set (pc) (if_then_else (ge (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "* OUTPUT_JUMP (\"bge %b0\", \"fbge %b0\", \"bmc %b0\");");; bmc ??(define_insn "bgeu" [(set (pc) (if_then_else (geu (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "bge %b0")(define_insn "ble" [(set (pc) (if_then_else (le (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "ble %b0")(define_insn "bleu" [(set (pc) (if_then_else (leu (cc0) (const_int 0)) (label_ref (match_operand 0 "" "")) (pc)))] "" "ble %b0");; Negated conditional jump instructions.(define_insn "" [(set (pc) (if_then_else (eq (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "*{ OUTPUT_JUMP (\"bne %b0\", \"fbne %b0\", \"bne %b0\");}")(define_insn "" [(set (pc) (if_then_else (ne (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "*{ OUTPUT_JUMP (\"beq %b0\", \"fbeq %b0\", \"beq %b0\");}")(define_insn "" [(set (pc) (if_then_else (gt (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "* OUTPUT_JUMP (\"ble %b0\", \"fbngt %b0\", 0);");; fbngt ???(define_insn "" [(set (pc) (if_then_else (gtu (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "ble %b0")(define_insn "" [(set (pc) (if_then_else (lt (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "* OUTPUT_JUMP (\"bge %b0\", \"fbnlt %b0\", \"jbmc %b0\");")(define_insn "" [(set (pc) (if_then_else (ltu (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "blt %b0")(define_insn "" [(set (pc) (if_then_else (ge (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "* OUTPUT_JUMP (\"blt %b0\", \"fbnge %b0\", \"jbms %b0\");")(define_insn "" [(set (pc) (if_then_else (geu (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "blt %b0");; ????(define_insn "" [(set (pc) (if_then_else (le (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "* OUTPUT_JUMP (\"bgt %b0\", \"fbnle %b0\", 0);")(define_insn "" [(set (pc) (if_then_else (leu (cc0) (const_int 0)) (pc) (label_ref (match_operand 0 "" ""))))] "" "bgt %b0");; Unconditional and other jump instructions(define_insn "jump" [(set (pc) (label_ref (match_operand 0 "" "")))] "" "bra %b0")(define_insn "tablejump" [(set (pc) (plus:SI (pc) (match_operand:SI 0 "general_operand" "r"))) (use (label_ref (match_operand 1 "" "")))] "" "jmp @(pc:b,4:4,%0)");;;; Should Add code for "ACB", "SCB". !!! ????;; See m68k.h (dbra);;;; Call subroutine with no return value.(define_insn "call" [(call (match_operand:QI 0 "general_operand" "m") (match_operand:SI 1 "general_operand" "rmi"))] ;; Operand 1 not really used on the Gmicro. "" "*{ if (GET_CODE (operands[0]) == MEM && GET_CODE (XEXP (operands[0],0)) == SYMBOL_REF) return \"bsr %b0\"; return \"jsr %0\";}");; Call subroutine, returning value in operand 0;; (which must be a hard register).(define_insn "call_value" [(set (match_operand 0 "" "=rf") (call (match_operand:QI 1 "general_operand" "m") (match_operand:SI 2 "general_operand" "rmi")))] ;; Operand 2 not really used on the Gmicro. "" "*{ if (GET_CODE (operands[1]) == MEM && GET_CODE (XEXP (operands[1],0)) == SYMBOL_REF) return \"bsr %b1\"; return \"jsr %1\";}")(define_insn "nop" [(const_int 0)] "" "nop");; Turned off because the general move-an-address pattern handles it.;; ;; Thus goes after the move instructions;; because the move instructions are better (require no spilling);; when they can apply. ;; After add/sub now !!;(define_insn "pushasi"; [(set (match_operand:SI 0 "push_operand" "=m"); (match_operand:SI 1 "address_operand" "p"))]; ""; "*;{; if (GET_CODE (operands[1]) == CONST_INT); return push_imm_word (INTVAL (operands[1]), operands[0]);; if (CONSTANT_P (operands[1])); return \"mov.w %1,%-\";; if (GET_CODE (operands[1]) == REG); return \"mov.w %1,%-\";; else if (GET_CODE (operands[1]) == MEM); {; return \"mov.w %1,%-\";; }; else; return \"mova.w %p1,%-\";;}");; This should not be used unless the add/sub insns can't be./* mova.[whq] 89.08.11 for test M.Yuhara */;(define_insn ""; [(set (match_operand:SI 0 "general_operand" "=rm"); (address (match_operand:SI 1 "address_operand" "p")))]; ""; "*;{; if (GET_CODE (operands[1]) == CONST_INT); return mov_imm_word (INTVAL (operands[1]), operands[0]);; if (CONSTANT_P (operands[1])); return \"mov.w %1,%0\";; if (GET_CODE (operands[1]) == REG); return \"mov.w %1,%0\";; else if (GET_CODE (operands[1]) == MEM) {; operands[1] = XEXP (operands[1],0);; return \"mov.w %1,%0\";; }; else; return \"mova.w %p1,%0\";;}")(define_insn "" [(set (match_operand:SI 0 "general_operand" "=rm") (address (match_operand:HI 1 "address_operand" "")))] "" "*{ if (GET_CODE (operands[1]) == CONST_INT) return mov_imm_word (INTVAL (operands[1]), operands[0]); if (CONSTANT_P (operands[1])) return \"mov.w %1,%0\"; if (GET_CODE (operands[1]) == REG) return \"mov.w %1,%0\"; else if (GET_CODE (operands[1]) == MEM) { operands[1] = XEXP (operands[1],0); return \"mov.w %1,%0\"; /* OK ? */ } else return \"mova.w %p1,%0\";}");(define_insn ""; [(set (match_operand:SI 0 "general_operand" "=rm"); (m
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -