📄 m68k.md
字号:
;;- Machine description for GNU compiler, Motorola 68000 Version;; Copyright (C) 1987, 1988, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2001, 2002, 2003;; Free Software Foundation, Inc.;; 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, 59 Temple Place - Suite 330,;; Boston, MA 02111-1307, USA.;;- Information about MCF5200 port.;;- The MCF5200 "ColdFire" architecture is a reduced version of the;;- 68k ISA. Differences include reduced support for byte and word;;- operands and the removal of BCD, bitfield, rotate, and integer;;- divide instructions. The TARGET_5200 flag turns the use of the;;- removed opcodes and addressing modes off.;;- ;;- instruction definitions;;- @@The original PO technology requires these to be ordered by speed,;;- @@ so that assigner will pick the fastest.;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.;;- When naming insn's (operand 0 of define_insn) be careful about using;;- names from other targets machine descriptions.;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code;;- updates for most instructions.;;- Operand classes for the register allocator:;;- 'a' one of the address registers can be used.;;- 'd' one of the data registers can be used.;;- 'f' one of the m68881 registers can be used;;- 'r' either a data or an address register can be used.;;- 'x' if one of the Sun FPA registers;;- 'y' if one of the Low Sun FPA registers (fpa0-fpa15).;;- Immediate Floating point operator constraints;;- 'G' a floating point constant that is *NOT* one of the standard;; 68881 constant values (to force calling output_move_const_double;; to get it from rom if it is a 68881 constant).;;- 'H' one of the standard FPA constant values;;;; See the functions standard_XXX_constant_p in output-m68k.c for more;; info.;;- Immediate integer operand constraints:;;- 'I' 1 .. 8;;- 'J' -32768 .. 32767;;- 'K' all integers EXCEPT -128 .. 127;;- 'L' -8 .. -1;;- 'M' all integers EXCEPT -256 .. 255;;- 'N' 24 .. 31;;- 'O' 16;;- 'P' 8 .. 15;;- Assembler specs:;;- "%." size separator ("." or "") move%.l d0,d1;;- "%#" immediate separator ("#" or "") move%.l %#0,d0;;- "%-" push operand "sp@-" move%.l d0,%-;;- "%+" pop operand "sp@+" move%.l d0,%+;;- "%@" top of stack "sp@" move%.l d0,%@;;- "%!" fpcr register;;- "%$" single-precision fp specifier ("s" or "") f%$add.x fp0,fp1;;- "%&" double-precision fp specifier ("d" or "") f%&add.x fp0,fp1;; UNSPEC usage:;; 1 This is a `sin' operation. The mode of the UNSPEC is MODE_FLOAT.;; operand 1 is the argument for `sin'.;; 2 This is a `cos' operation. The mode of the UNSPEC is MODE_FLOAT.;; operand 1 is the argument for `cos'.;;- Information about 68040 port.;;- The 68040 executes all 68030 and 68881/2 instructions, but some must;;- be emulated in software by the OS. It is faster to avoid these;;- instructions and issue a library call rather than trapping into;;- the kernel. The affected instructions are fintrz and fscale. The;;- TARGET_68040 flag turns the use of the opcodes off.;;- The '040 also implements a set of new floating-point instructions;;- which specify the rounding precision in the opcode. This finally;;- permit the 68k series to be truly IEEE compliant, and solves all;;- issues of excess precision accumulating in the extended registers.;;- By default, GCC does not use these instructions, since such code will;;- not run on an '030. To use these instructions, use the -m68040-only;;- switch. By changing TARGET_DEFAULT to include TARGET_68040_ONLY,;;- you can make these instructions the default.;;- These new instructions aren't directly in the md. They are brought;;- into play by defining "%$" and "%&" to expand to "s" and "d" rather;;- than "".;;- Information about 68060 port.;;- The 68060 executes all 68030 and 68881/2 instructions, but some must;;- be emulated in software by the OS. It is faster to avoid these;;- instructions and issue a library call rather than trapping into;;- the kernel. The affected instructions are: divs.l <ea>,Dr:Dq;;;- divu.l <ea>,Dr:Dq; muls.l <ea>,Dr:Dq; mulu.l <ea>,Dr:Dq; and;;- fscale. The TARGET_68060 flag turns the use of the opcodes off.;;- FPA port explanation:;;- Usage of the Sun FPA and the 68881 together;;- The current port of gcc to the sun fpa disallows use of the m68881;;- instructions completely if code is targeted for the fpa. This is;;- for the following reasons:;;- 1) Expressing the preference hierarchy (ie. use the fpa if you;;- can, the 68881 otherwise, and data registers only if you are;;- forced to it) is a bitch with the current constraint scheme,;;- especially since it would have to work for any combination of;;- -mfpa, -m68881.;;- 2) There are no instructions to move between the two types of;;- registers; the stack must be used as an intermediary.;;- It could indeed be done; I think the best way would be to have;;- separate patterns for TARGET_FPA (which implies a 68881),;;- TARGET_68881, and no floating point co-processor. Use;;- define_expands for all of the named instruction patterns, and;;- include code in the FPA instruction to deal with the 68881 with;;- preferences specifically set to favor the fpa. Some of this has;;- already been done:;;-;;- 1) Separation of most of the patterns out into a TARGET_FPA;;- case and a TARGET_68881 case (the exceptions are the patterns;;- which would need one define_expand and three define_insn's under;;- it (with a lot of duplicate code between them) to replace the;;- current single define_insn. These are mov{[ds]f,[ds]i} and the;;- first two patterns in the md.;;-;;- Some would still have to be done:;;-;;- 1) Add code to the fpa patterns which correspond to 68881;;- patterns to deal with the 68881 case (including preferences!).;;- What you might actually do here is combine the fpa and 68881 code;;- back together into one pattern for those instructions where it's;;- absolutely necessary and save yourself some duplicate code. I'm;;- not completely sure as to whether you could get away with doing;;- this only for the mov* insns, or if you'd have to do it for all;;- named insns.;;- 2) Add code to the mov{[ds]f,[ds]i} instructions to handle;;- moving between fpa regs and 68881 regs.;;- Since the fpa is more powerful than the 68881 and also has more;;- registers, and since I think the resultant md would be medium ugly;;- (lot's of duplicate code, ugly constraint strings), I elected not;;- to do this change.;;- Another reason why someone *might* want to do the change is to;;- control which register classes are accessed in a slightly cleaner;;- way than I have. See the blurb on CONDITIONAL_REGISTER_USAGE in;;- the internals manual.;;- Yet another reason why someone might want to do this change is to;;- allow use of some of the 68881 insns which have no equivalent on;;- the fpa. The sqrt instruction comes fairly quickly to mind.;;- If this is ever done, don't forget to change sun3.h so that;;- it *will* define __HAVE_68881__ when the FPA is in use.;;- Condition code hack;;- When a floating point compare is done in the fpa, the resulting;;- condition codes are left in the fpastatus register. The values in;;- this register must be moved into the 68000 cc register before any;;- jump is executed. Once this has been done, regular jump;;- instructions are fine (ie. floating point jumps are not necessary.;;- They are only done if the cc is in the 68881).;;- The instructions that move the fpastatus register to the 68000;;- register clobber a data register (the move cannot be done direct).;;- These instructions might be bundled either with the compare;;- instruction, or the branch instruction. If we were using both the;;- fpa and the 68881 together, we would wish to only mark the;;- register clobbered if we were doing the compare in the fpa, but I;;- think that that decision (whether to clobber the register or not);;- must be done before register allocation (makes sense) and hence we;;- can't know if the floating point compare will be done in the fpa;;- or the fp. So whenever we are asked for code that uses the fpa,;;- we will mark a data register as clobbered. This is reasonable, as;;- almost all floating point compare operations done with fpa code;;- enabled will be done in the fpa. It's even more reasonable since;;- we decided to make the 68881 and the fpa mutually exclusive.;;- We place to code to move the fpastatus register inside of a;;- define_expand so that we can do it conditionally based on whether;;- we are targeting an fpa or not.;;- This still leaves us with the question of where we wish to put the;;- code to move the fpastatus reg. If we put it in the compare;;- instruction, we can restrict the clobbering of the register to;;- floating point compares, but we can't take advantage of floating;;- point subtracts & etc. that alter the fpastatus register. If we;;- put it in the branch instruction, all branches compiled with fpa;;- code enabled will clobber a data register, but we will be able to;;- take advantage of fpa subtracts. This balance favors putting the;;- code in with the compare instruction.;;- Note that if some enterprising hacker should decide to switch;;- this, he'll need to modify the code in NOTICE_UPDATE_CC.;;- Usage of the top 16 fpa registers;;- The only locations which we may transfer fpa registers 16-31 from;;- or to are the fpa registers 0-15. (68000 registers and memory;;- locations are impossible). This causes problems in gcc, which;;- assumes that mov?? instructions require no additional registers;;- (see section 11.7) and since floating point moves *must* be;;- supported into general registers (see section 12.3 under;;- HARD_REGNO_OK_FOR_MODE_P) from anywhere.;;- My solution was to reserve fpa0 for moves into or out of these top;;- 16 registers and to disparage the choice to reload into or out of;;- these registers as much as I could. That alternative is always;;- last in the list, so it will not be used unless all else fails. I;;- will note that according to my current information, sun's compiler;;- doesn't use these top 16 registers at all.;;- There is another possible way to do it. I *believe* that if you;;- make absolutely sure that the code will not be executed in the;;- reload pass, you can support the mov?? names with define_expands;;- which require new registers. This may be possible by the;;- appropriate juggling of constraints. I may come back to this later.;;- Usage of constant RAM;;- This has been handled correctly (I believe) but the way I've done;;- it could use a little explanation. The constant RAM can only be;;- accessed when the instruction is in "command register" mode.;;- "command register" mode means that no accessing of memory or the;;- 68000 registers is being done. This can be expressed easily in;;- constraints, so generally the mode of the instruction is;;- determined by a branch off of which_alternative. In outputting;;- instructions, a 'w' means to output an access to the constant ram;;- (if the arg is CONST_DOUBLE and is one of the available;;- constants), and 'x' means to output a register pair (if the arg is;;- a 68000 register) and a 'y' is the combination of the above two;;- processes. You use a 'y' in two operand DF instructions where you;;- *know* the other operand is an fpa register, you use an 'x' in DF;;- instructions where the arg might be a 68000 register and the;;- instruction is *not* in "command register" mode, and you use a 'w';;- in two situations: 1) The instruction *is* in command register;;- mode (and hence won't be accessing 68000 registers), or 2) The;;- instruction is a two operand SF instruction where you know the;;- other operand is an fpa register.;;- Optimization issues;;- I actually think that I've included all of the fpa instructions;;- that should be included. Note that if someone is interested in;;- doing serious floating point work on the sun fpa, I would advise;;- the use of the "asm" instruction in gcc to allow you to use the;;- sin, cos, and exponential functions on the fpa board.;;- END FPA Explanation Section.;;- Some of these insn's are composites of several m68000 op codes.;;- The assembler (or final @@??) insures that the appropriate one is;;- selected.(define_insn "" [(set (match_operand:DF 0 "push_operand" "=m") (match_operand:DF 1 "general_operand" "ro<>fyE"))] "" "*{ if (FP_REG_P (operands[1])) return \"fmove%.d %f1,%0\"; if (FPA_REG_P (operands[1])) return \"fpmove%.d %1, %x0\"; return output_move_double (operands);}")(define_insn "pushdi" [(set (match_operand:DI 0 "push_operand" "=m") (match_operand:DI 1 "general_operand" "ro<>Fyi"))] "" "*{ return output_move_double (operands);}");; We don't want to allow a constant operand for test insns because;; (set (cc0) (const_int foo)) has no mode information. Such insns will;; be folded while optimizing anyway.(define_expand "tstdi" [(parallel [(set (cc0) (match_operand:DI 0 "nonimmediate_operand" "")) (clobber (match_scratch:SI 1 "")) (clobber (match_scratch:DI 2 ""))])] "" "m68k_last_compare_had_fp_operands = 0;")(define_insn "" [(set (cc0) (match_operand:DI 0 "nonimmediate_operand" "am,d")) (clobber (match_scratch:SI 1 "=X,d")) (clobber (match_scratch:DI 2 "=d,X"))] "" "*{ if (which_alternative == 0) { rtx xoperands[2]; xoperands[0] = operands[2]; xoperands[1] = operands[0]; output_move_double (xoperands); cc_status.flags |= CC_REVERSED; return \"neg%.l %R2\;negx%.l %2\"; } if (find_reg_note (insn, REG_DEAD, operands[0])) { cc_status.flags |= CC_REVERSED; return \"neg%.l %R0\;negx%.l %0\"; } else /* ** 'sub' clears %1, and also clears the X cc bit ** 'tst' sets the Z cc bit according to the low part of the DImode operand ** 'subx %1' (i.e. subx #0) acts as a (non-existent) tstx on the high part */ return \"sub%.l %1,%1\;tst%.l %R0\;subx%.l %1,%0\";}")(define_expand "tstsi" [(set (cc0) (match_operand:SI 0 "nonimmediate_operand" ""))] "" "m68k_last_compare_had_fp_operands = 0;")(define_insn "" [(set (cc0) (match_operand:SI 0 "nonimmediate_operand" "rm"))] "" "*{#ifdef ISI_OV /* ISI's assembler fails to handle tstl a0. */ if (! ADDRESS_REG_P (operands[0]))#else if (TARGET_68020 || TARGET_5200 || ! ADDRESS_REG_P (operands[0]))#endif return \"tst%.l %0\"; /* If you think that the 68020 does not support tstl a0, reread page B-167 of the 68020 manual more carefully. */ /* On an address reg, cmpw may replace cmpl. */#ifdef SGS_CMP_ORDER return \"cmp%.w %0,%#0\";#else return \"cmp%.w %#0,%0\";#endif}");; This can't use an address register, because comparisons;; with address registers as second operand always test the whole word.(define_expand "tsthi" [(set (cc0) (match_operand:HI 0 "nonimmediate_operand" ""))] "" "m68k_last_compare_had_fp_operands = 0;")(define_insn "" [(set (cc0) (match_operand:HI 0 "nonimmediate_operand" "dm"))] "" "tst%.w %0")(define_expand "tstqi" [(set (cc0) (match_operand:QI 0 "nonimmediate_operand" ""))] "" "m68k_last_compare_had_fp_operands = 0;")(define_insn "" [(set (cc0) (match_operand:QI 0 "nonimmediate_operand" "dm"))] "" "tst%.b %0")(define_expand "tstsf" [(set (cc0) (match_operand:SF 0 "general_operand" ""))] "TARGET_68881 || TARGET_FPA" "{ m68k_last_compare_had_fp_operands = 1; if (TARGET_FPA) { emit_insn (gen_tstsf_fpa (operands[0])); DONE; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -