📄 arm.md
字号:
;;- Machine description Acorn RISC Machine for GNU compiler;; Copyright (C) 1991 Free Software Foundation, Inc.;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl);; and Martin Simmons (@harleqn.co.uk).;; This file is part of GNU CC.;; GNU CC is free software; you can redistribute it and/or modify;; it under the terms of the GNU General Public License as published by;; the Free Software Foundation; either version 2, or (at your option);; any later version.;; GNU CC is distributed in the hope that it will be useful,;; but WITHOUT ANY WARRANTY; without even the implied warranty of;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the;; GNU General Public License for more details.;; You should have received a copy of the GNU General Public License;; along with GNU CC; see the file COPYING. If not, write to;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.;; Every template must be output by arm_output_asm_insn, since this keeps;; track of the offset of labels within the text segment. This is needed to;; to be able to (correctly) output instructions for loading a value from a;; function's constant pool, since different instructions are needed when the;; constant pool is more than 4095 bytes away from the PC.;; Addition insns.(define_insn "adddi3" [(set (match_operand:DI 0 "di_operand" "=&r") (plus:DI (match_operand:DI 1 "di_operand" "%r") (match_operand:DI 2 "di_operand" "r")))] "" "* arm_output_asm_insn (\"adds\\t%0, %1, %2\", operands); return (arm_output_asm_insn (\"adc\\t%R0, %R1, %R2\", operands));")(define_insn "addsi3" [(set (match_operand:SI 0 "register_operand" "=r,r") (plus:SI (match_operand:SI 1 "register_operand" "r,r") (match_operand:SI 2 "general_operand" "r,n")))] "" "* switch (which_alternative) { case 0: return (arm_output_asm_insn (\"add\\t%0, %1, %2\", operands)); case 1: return (output_add_immediate (operands)); }")(define_insn "addsf3" [(set (match_operand:SF 0 "register_operand" "=f") (plus:SF (match_operand:SF 1 "register_operand" "f") (match_operand:SF 2 "fpu_rhs_operand" "fG")))] "" "* return (arm_output_asm_insn (\"adfs\\t%0, %1, %2\", operands));")(define_insn "adddf3" [(set (match_operand:DF 0 "register_operand" "=f") (plus:DF (match_operand:DF 1 "register_operand" "f") (match_operand:DF 2 "fpu_rhs_operand" "fG")))] "" "* return (arm_output_asm_insn (\"adfd\\t%0, %1, %2\", operands));")(define_insn "subdi3" [(set (match_operand:DI 0 "di_operand" "=&r") (minus:DI (match_operand:DI 1 "di_operand" "%r") (match_operand:DI 2 "di_operand" "r")))] "" "* arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands); return (arm_output_asm_insn (\"sbc\\t%R0, %R1, %R2\", operands));")(define_insn "subsi3" [(set (match_operand:SI 0 "register_operand" "=r,r,r") (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I") (match_operand:SI 2 "general_operand" "r,n,r")))] "" "* switch (which_alternative) { case 0: return (arm_output_asm_insn (\"sub\\t%0, %1, %2\", operands)); case 1: operands[2] = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[2])); return (output_add_immediate (operands)); case 2: return (arm_output_asm_insn (\"rsb\\t%0, %2, %1\", operands)); }")(define_insn "subsf3" [(set (match_operand:SF 0 "register_operand" "=f,f") (minus:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G") (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))] "" "* switch (which_alternative) { case 0: return (arm_output_asm_insn (\"sufs\\t%0, %1, %2\", operands)); case 1: return (arm_output_asm_insn (\"rsfs\\t%0, %2, %1\", operands)); }")(define_insn "subdf3" [(set (match_operand:DF 0 "register_operand" "=f,f") (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G") (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))] "" "* switch (which_alternative) { case 0: return (arm_output_asm_insn (\"sufd\\t%0, %1, %2\", operands)); case 2: return (arm_output_asm_insn (\"rsfd\\t%0, %2, %1\", operands)); }");; Multiplication insns;; The `&' is too strict, but at least generates correct code.(define_insn "mulsi3" [(set (match_operand:SI 0 "register_operand" "=&r") (mult:SI (match_operand:SI 1 "register_operand" "%r") (match_operand:SI 2 "register_operand" "r")))] "" "* if (REGNO (operands[0]) == REGNO (operands[1])) return (arm_output_asm_insn (\"mul\\t%0, %2, %1\", operands)); else return (arm_output_asm_insn (\"mul\\t%0, %1, %2\", operands));");; Unnamed templates to match MLA instruction.(define_insn "" [(set (match_operand:SI 0 "register_operand" "=&r") (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r") (match_operand:SI 2 "register_operand" "r")) (match_operand:SI 3 "register_operand" "r")))] "" "* if (REGNO (operands[0]) == REGNO (operands[1])) return (arm_output_asm_insn (\"mla\\t%0, %2, %1, %3\", operands)); else return (arm_output_asm_insn (\"mla\\t%0, %1, %2, %3\", operands));")(define_insn "" [(set (match_operand:SI 0 "register_operand" "=&r") (plus:SI (match_operand:SI 3 "register_operand" "r") (mult:SI (match_operand:SI 1 "register_operand" "%r") (match_operand:SI 2 "register_operand" "r"))))] "" "* if (REGNO (operands[0]) == REGNO (operands[1])) return (arm_output_asm_insn (\"mla\\t%0, %2, %1, %3\", operands)); else return (arm_output_asm_insn (\"mla\\t%0, %1, %2, %3\", operands));")(define_insn "mulsf3" [(set (match_operand:SF 0 "register_operand" "=f") (mult:SF (match_operand:SF 1 "register_operand" "f") (match_operand:SF 2 "fpu_rhs_operand" "fG")))] "" "*return (arm_output_asm_insn (\"mufs\\t%0, %1, %2\", operands));")(define_insn "muldf3" [(set (match_operand:DF 0 "register_operand" "=f") (mult:DF (match_operand:DF 1 "register_operand" "f") (match_operand:DF 2 "fpu_rhs_operand" "fG")))] "" "* return (arm_output_asm_insn (\"mufd\\t%0, %1, %2\", operands));");; Division insns(define_insn "divsf3" [(set (match_operand:SF 0 "register_operand" "=f,f") (div:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G") (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))] "" "* switch (which_alternative) { case 0: return (arm_output_asm_insn (\"dvfs\\t%0, %1, %2\", operands)); case 1: return (arm_output_asm_insn (\"rdfs\\t%0, %2, %1\", operands)); }")(define_insn "divdf3" [(set (match_operand:DF 0 "register_operand" "=f,f") (div:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G") (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))] "" "* switch (which_alternative) { case 0: return (arm_output_asm_insn (\"dvfd\\t%0, %1, %2\", operands)); case 1: return (arm_output_asm_insn (\"rdfd\\t%0, %2, %1\", operands)); }");; Modulo insns(define_insn "modsf3" [(set (match_operand:SF 0 "register_operand" "=f") (mod:SF (match_operand:SF 1 "register_operand" "f") (match_operand:SF 2 "fpu_rhs_operand" "fG")))] "" "* return (arm_output_asm_insn (\"rmfs\\t%0, %1, %2\", operands));")(define_insn "moddf3" [(set (match_operand:DF 0 "register_operand" "=f") (mod:DF (match_operand:DF 1 "register_operand" "f") (match_operand:DF 2 "fpu_rhs_operand" "fG")))] "" "* return (arm_output_asm_insn (\"rmfd\\t%0, %1, %2\", operands));");; Boolean and,ior,xor insns(define_insn "anddi3" [(set (match_operand:DI 0 "di_operand" "=&r") (and:DI (match_operand:DI 1 "di_operand" "%r") (match_operand:DI 2 "di_operand" "r")))] "" "* arm_output_asm_insn (\"and\\t%0, %1, %2\", operands); return (arm_output_asm_insn (\"and\\t%R0, %R1, %R2\", operands));")(define_insn "andsi3" [(set (match_operand:SI 0 "register_operand" "=r") (and:SI (match_operand:SI 1 "register_operand" "r") (match_operand:SI 2 "arm_rhs_operand" "rI")))] "" "* return (arm_output_asm_insn (\"and\\t%0, %1, %2\", operands));")(define_insn "andcbsi3" [(set (match_operand:SI 0 "register_operand" "=r") (and:SI (match_operand:SI 1 "register_operand" "r") (not:SI (match_operand:SI 2 "arm_rhs_operand" "rI"))))] "" "* return (arm_output_asm_insn (\"bic\\t%0, %1, %2\", operands));")(define_insn "iordi3" [(set (match_operand:DI 0 "di_operand" "=&r") (ior:DI (match_operand:DI 1 "di_operand" "%r") (match_operand:DI 2 "di_operand" "r")))] "" "* arm_output_asm_insn (\"orr\\t%0, %1, %2\", operands); return (arm_output_asm_insn (\"orr\\t%R0, %R1, %R2\", operands));")(define_insn "iorsi3" [(set (match_operand:SI 0 "register_operand" "=r,r") (ior:SI (match_operand:SI 1 "register_operand" "r,r") (match_operand:SI 2 "nonmemory_operand" "r,n")))] "" "* switch (which_alternative) { case 0: return (arm_output_asm_insn (\"orr\\t%0, %1, %2\", operands)); case 1: return (output_multi_immediate (operands, \"orr\\t%0, %1, %2\", \"orr\\t%0, %0, %2\", 2, INTVAL (operands[2]))); }")(define_insn "xorsi3" [(set (match_operand:SI 0 "register_operand" "=r,r") (xor:SI (match_operand:SI 1 "register_operand" "r,r") (match_operand:SI 2 "nonmemory_operand" "r,n")))] "" "* switch (which_alternative) { case 0: return (arm_output_asm_insn (\"eor\\t%0, %1, %2\", operands)); case 1: return (output_multi_immediate (operands, \"eor\\t%0, %1, %2\", \"eor\\t%0, %0, %2\", 2, INTVAL (operands[2]))); }");; Shift and rotation insns(define_insn "ashlsi3" [(set (match_operand:SI 0 "register_operand" "=r") (ashift:SI (match_operand:SI 1 "register_operand" "r") (match_operand:SI 2 "general_operand" "rn")))] "" "* return (output_shifted_move (ASHIFT, operands));")(define_insn "ashrsi3" [(set (match_operand:SI 0 "register_operand" "=r") (ashiftrt:SI (match_operand:SI 1 "register_operand" "r") (match_operand:SI 2 "general_operand" "rn")))] "" "* return (output_shifted_move (ASHIFTRT, operands));");; lshlsi3 is not defined because shift counts cannot be negative;; An unnamed pattern is needed for expansion of zero_extend.(define_insn "" [(set (match_operand:SI 0 "register_operand" "=r") (lshift:SI (match_operand:SI 1 "register_operand" "r") (match_operand:SI 2 "general_operand" "rn")))] "" "* return (output_shifted_move (LSHIFT, operands));")(define_insn "lshrsi3" [(set (match_operand:SI 0 "register_operand" "=r") (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") (match_operand:SI 2 "general_operand" "rn")))] "" "* return (output_shifted_move (LSHIFTRT, operands));");; rotlsi3 is not defined yet to see what happens(define_insn "rotrsi3" [(set (match_operand:SI 0 "register_operand" "=r,r") (rotatert:SI (match_operand:SI 1 "register_operand" "r,r") (match_operand:SI 2 "general_operand" "r,n")))] "" "* switch (which_alternative) { case 0: return (arm_output_asm_insn (\"mov\\t%0, %1,ror %2\", operands)); case 1: if (INTVAL(operands[2]) > 31) operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[2]) % 32); return (arm_output_asm_insn (\"mov\\t%0, %1,ror%2\", operands)); }");; Unary arithmetic insns(define_insn "negdi2" [(set (match_operand:DI 0 "di_operand" "=&r") (neg:DI (match_operand:DI 1 "di_operand" "r")))] "" "* arm_output_asm_insn (\"rsb\\t%0, %1, #0\", operands); return (arm_output_asm_insn (\"rsc\\t%R0, %R1, #0\", operands));")(define_insn "negsi2" [(set (match_operand:SI 0 "register_operand" "=r") (neg:SI (match_operand:SI 1 "register_operand" "r")))] "" "* return (arm_output_asm_insn (\"rsb\\t%0, %1, #0\", operands));")(define_insn "negsf2" [(set (match_operand:SF 0 "register_operand" "=f") (neg:SF (match_operand:SF 1 "register_operand" "f")))] "" "* return (arm_output_asm_insn (\"mnfs\\t%0, %1\", operands));")(define_insn "negdf2" [(set (match_operand:DF 0 "register_operand" "=f") (neg:DF (match_operand:DF 1 "register_operand" "f")))] "" "* return (arm_output_asm_insn (\"mnfd\\t%0, %1\", operands));")(define_insn "abssf2" [(set (match_operand:SF 0 "register_operand" "=f") (abs:SF (match_operand:SF 1 "register_operand" "f")))] "" "* return (arm_output_asm_insn (\"abss\\t%0, %1\", operands));")(define_insn "absdf2" [(set (match_operand:DF 0 "register_operand" "=f") (abs:DF (match_operand:DF 1 "register_operand" "f")))] "" "* return (arm_output_asm_insn (\"absd\\t%0, %1\", operands));")(define_insn "sqrtsf2" [(set (match_operand:SF 0 "register_operand" "=f") (sqrt:SF (match_operand:SF 1 "register_operand" "f")))] "" "* return (arm_output_asm_insn (\"sqts\\t%0, %1\", operands));")(define_insn "sqrtdf2" [(set (match_operand:DF 0 "register_operand" "=f")
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -