📄 gmicro.md
字号:
return \"mov.w %1,%0;shl.w #16,%0;shl.w #-24,%0\"; break; case 24: return \"movu %1.b,%0.w\"; break; default: myabort (2); } } else { switch (INTVAL (operands[3])) { case 0: return \"mov.w %1,%0;shl.w #-16,%0\"; break; case 16: return \"movu %1.h,%0.w\"; break; default: myabort (3); } } } else { if (INTVAL (operands[2]) == 8) return \"movu %1.h,%0.w\"; else return \"movu %1.b,%0.w\"; } } else { /* op[0] == MEM */ if (INTVAL (operands[2]) == 8) return \"movu %1.b,%0.w\"; return \"movu %1.h,%0.w\"; }}")(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\";}");; Call subroutine returning any type.(define_expand "untyped_call" [(parallel [(call (match_operand 0 "" "") (const_int 0)) (match_operand 1 "" "") (match_operand 2 "" "")])] "" "{ int i; emit_call_insn (gen_call (operands[0], const0_rtx, NULL, const0_rtx)); for (i = 0; i < XVECLEN (operands[2], 0); i++) { rtx set = XVECEXP (operands[2], 0, i); emit_move_insn (SET_DEST (set), SET_SRC (set)); } /* The optimizer does not know that the call sets the function value registers we stored in the result block. We avoid problems by claiming that all hard registers are used and clobbered at this point. */ emit_insn (gen_blockage ()); DONE;}");; UNSPEC_VOLATILE is considered to use and clobber all hard registers and;; all of memory. This blocks insns from being moved across this point.(define_insn "blockage" [(unspec_volatile [(const_int 0)] 0)] "" "")(define_insn "nop" [(const_int 0)] "
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -