⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 m68k.md

📁 这是完整的gcc源代码
💻 MD
📖 第 1 页 / 共 5 页
字号:
;;- Machine description for GNU compiler;;- Motorola 68000 Version;;   Copyright (C) 1987, 1988 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 1, 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.;;- 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'  -128 .. 127;;- 'L'  -8 .. -1;;- 		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 targetted 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;;- seperate 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 alot 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 reultant 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 tm-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 tagetting 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 exectued 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 outputing;;- 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;;- processies.  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<>fyF"))]  ""  "*{  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 ""  [(set (match_operand:DI 0 "push_operand" "=m")	(match_operand:DI 1 "general_operand" "ro<>Fy"))]  ""  "*{  return output_move_double (operands);}");; Put tstsi first among test insns so it matches a CONST_INT operand.(define_insn "tstsi"  [(set (cc0)	(match_operand:SI 0 "general_operand" "rm"))]  ""  "*{#ifdef ISI_OV  /* ISI's assembler fails to handle tstl a0.  */  if (! ADDRESS_REG_P (operands[0]))#else  if (TARGET_68020 || ! 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 HPUX_ASM  return \"cmp%.w %0,%#0\";#else  return \"cmp%.w %#0,%0\";#endif}")(define_insn "tsthi"  [(set (cc0)	(match_operand:HI 0 "general_operand" "rm"))]  ""  "*{#ifdef ISI_OV  if (! ADDRESS_REG_P (operands[0]))#else  if (TARGET_68020 || ! ADDRESS_REG_P (operands[0]))#endif    return \"tst%.w %0\";#ifdef HPUX_ASM  return \"cmp%.w %0,%#0\";#else  return \"cmp%.w %#0,%0\";#endif}")(define_insn "tstqi"  [(set (cc0)	(match_operand:QI 0 "general_operand" "dm"))]  ""  "tst%.b %0")  (define_expand "tstsf"  [(set (cc0)	(match_operand:SF 0 "general_operand" ""))]  "TARGET_68881 || TARGET_FPA"  "{  if (TARGET_FPA)    {      emit_insn (gen_rtx (PARALLEL, VOIDmode,		          gen_rtvec (2,				     gen_rtx (SET, VOIDmode,					      cc0_rtx, operands[0]),				     gen_rtx (CLOBBER, VOIDmode,					      gen_reg_rtx (SImode)))));      DONE;    }}")(define_insn ""  [(set (cc0)	(match_operand:SF 0 "general_operand" "xmdF"))   (clobber (match_operand:SI 1 "general_operand" "d"))]  "TARGET_FPA"  "fptst%.s %x0\;fpmove fpastatus,%1\;movw %1,cc")(define_insn ""  [(set (cc0)	(match_operand:SF 0 "general_operand" "fdm"))]  "TARGET_68881"  "*{  cc_status.flags = CC_IN_68881;  if (FP_REG_P (operands[0]))    return \"ftst%.x %0\";  return \"ftst%.s %0\";}")(define_expand "tstdf"  [(set (cc0)	(match_operand:DF 0 "general_operand" ""))]  "TARGET_68881 || TARGET_FPA"  "{  if (TARGET_FPA)    {      emit_insn (gen_rtx (PARALLEL, VOIDmode,			  gen_rtvec (2, gen_rtx (SET, VOIDmode,						 cc0_rtx, operands[0]),				     gen_rtx (CLOBBER, VOIDmode,					      gen_reg_rtx (SImode)))));      DONE;    }}")(define_insn ""  [(set (cc0)	(match_operand:DF 0 "general_operand" "xrmF"))   (clobber (match_operand:SI 1 "general_operand" "d"))]  "TARGET_FPA"  "fptst%.d %x0\;fpmove fpastatus,%1\;movw %1,cc")(define_insn ""  [(set (cc0)	(match_operand:DF 0 "general_operand" "fm"))]  "TARGET_68881"  "*{  cc_status.flags = CC_IN_68881;  if (FP_REG_P (operands[0]))    return \"ftst%.x %0\";  return \"ftst%.d %0\";}");; compare instructions.;; Put cmpsi first among compare insns so it matches two CONST_INT operands.;; A composite of the cmp, cmpa, & cmpi m68000 op codes.(define_insn "cmpsi"  [(set (cc0)	(compare (match_operand:SI 0 "general_operand" "rKs,mr,>")		 (match_operand:SI 1 "general_operand" "mr,Ksr,>")))]  ""  "*{  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)    return \"cmpm%.l %1,%0\";  if (REG_P (operands[1])      || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))    { cc_status.flags |= CC_REVERSED;#ifdef HPUX_ASM      return \"cmp%.l %d1,%d0\";#else      return \"cmp%.l %d0,%d1\"; #endif    }#ifdef HPUX_ASM  return \"cmp%.l %d0,%d1\";#else  return \"cmp%.l %d1,%d0\";#endif}")(define_insn "cmphi"  [(set (cc0)	(compare (match_operand:HI 0 "general_operand" "rnm,d,n,m")		 (match_operand:HI 1 "general_operand" "d,rnm,m,n")))]  ""  "*{  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)    return \"cmpm%.w %1,%0\";  if ((REG_P (operands[1]) && !ADDRESS_REG_P (operands[1]))      || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))    { cc_status.flags |= CC_REVERSED;#ifdef HPUX_ASM      return \"cmp%.w %d1,%d0\";#else      return \"cmp%.w %d0,%d1\"; #endif    }#ifdef HPUX_ASM  return \"cmp%.w %d0,%d1\";#else  return \"cmp%.w %d1,%d0\";#endif}")(define_insn "cmpqi"  [(set (cc0)	(compare (match_operand:QI 0 "general_operand" "dn,md,>")		 (match_operand:QI 1 "general_operand" "dm,nd,>")))]  ""  "*{  if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)    return \"cmpm%.b %1,%0\";  if (REG_P (operands[1])      || (!REG_P (operands[0]) && GET_CODE (operands[0]) != MEM))    { cc_status.flags |= CC_REVERSED;#ifdef HPUX_ASM      return \"cmp%.b %d1,%d0\";#else      return \"cmp%.b %d0,%d1\";#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -