File:  [gforth] / gforth / asm / numref.fs
Revision 1.7: download - view: text, annotated - select for diffs
Mon Aug 25 14:17:49 2003 UTC (20 years, 7 months ago) by anton
Branches: MAIN
CVS tags: v0-6-2, HEAD
documentation updates
fixed some portability bugs in vmgen-ex and vmgen-ex2
updated copyright years

    1: \ numref.fs
    2: 
    3: \ Copyright (C) 1998,2001,2003 Free Software Foundation, Inc.
    4: 
    5: \ This file is part of Gforth.
    6: 
    7: \ Gforth is free software; you can redistribute it and/or
    8: \ modify it under the terms of the GNU General Public License
    9: \ as published by the Free Software Foundation; either version 2
   10: \ of the License, or (at your option) any later version.
   11: 
   12: \ This program is distributed in the hope that it will be useful,
   13: \ but WITHOUT ANY WARRANTY; without even the implied warranty of
   14: \ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15: \ GNU General Public License for more details.
   16: 
   17: \ You should have received a copy of the GNU General Public License
   18: \ along with this program; if not, write to the Free Software
   19: \ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
   20: 
   21: 0 [IF]
   22: 
   23: This is a generic solution for doing labels (forward and backward
   24: references) in an assembler program.
   25: 
   26: How to use local labels
   27: =======================
   28: 
   29: Example:
   30: 
   31: Label 10pause
   32: 		10 # ldy,
   33: 	1 $:	dey,
   34: 		1 $ bne,
   35: 		rts,
   36: End-Label
   37: 
   38: "n $:" defines an address reference. "n $" returns the address of the
   39: reference defined with "n $:".
   40: 
   41: 
   42: How to embed local labels in your assembler
   43: ===========================================
   44: 
   45: At the moment all references are forward references, meaning all
   46: references are resolved at the end of the definition.
   47: 
   48: The Simple Resolver
   49: -------------------
   50: 
   51: The only special thing is how a label is resolved. Numref does this by
   52: executing a resolver-word. For example, consider a two byte opcode
   53: with the second byte as branch-offset. The resolver-word would look
   54: like this:
   55: 
   56: : doresolve ( iaddr -- )
   57:   dup ref-addr @ - swap 1+ X c! ;
   58: 
   59: iaddr is the address of the instruction with the reference that must
   60: be resolved. The destination address of the reference is stored at ref-addr.
   61: 
   62: The resolver-word must be registered like this:
   63: 
   64:  "' doresolve TO std-resolver"
   65: 
   66: This is not a deferred word!
   67: 
   68: Complex Resolving
   69: -----------------
   70: 
   71: To support different cpu-instruction with different operand formats it
   72: is possible to find out the type of opcode by accessing the target's
   73: memory in doresolve. This works for very simple processors, e.g. for
   74: 6502 it is very easy to find out whether we have a 2-byte absolute
   75: address or a 1-byte relative address.
   76: 
   77: If this method is too difficult, it is possible to store additional
   78: information in the resolve structure.
   79: 
   80: When assembling an opcode you should find out whether the address is a
   81: reference and then store the xt of a special resolver word in the
   82: resolve structure by "ref-resolver !", or store some additional data
   83: in the resolve structure by "ref-data !", if one data field is not
   84: enough, allocate memory and use ref-data as pointer to it.
   85: 
   86: Internal structure
   87: ==================
   88: 
   89: There is a heap buffer to store the references.  The structure of one
   90: entry is:
   91: 
   92:  1 cell		ref-link
   93:  1 cell		ref-flag	\ mixture of tag-number
   94: 				\ and tag type
   95:  1 cell		ref-resolver	\ xt of resolver
   96:  1 cell		ref-addr	\ pointer to destination or on reference
   97: 				\ instruction
   98: 				\ (start of the instruction)
   99:  1 cell		ref-data	\ additional information for resolver
  100: 
  101: [THEN]
  102: 
  103: require ./basic.fs
  104: 
  105: also assembler definitions
  106: 
  107: hex
  108: 
  109: 0 value ref-marker \ tells us that address is an reference
  110: 
  111: 0 value ref-now	\ points to the reference we are working on
  112: 
  113: : ref-link ref-now ;
  114: : ref-flag ref-now cell+ ;
  115: : ref-resolver ref-now 2 cells + ;
  116: : ref-adr ref-now 3 cells + ;
  117: : ref-addr ref-now 3 cells + ;
  118: : ref-data ref-now 4 cells + ;
  119: : ref-tag-len 5 cells ;
  120: 
  121: : ref-resolve ref-resolver @ execute ;
  122: 
  123: : ref? 	( -- )
  124: 	ref-marker
  125: 	false TO ref-marker ;
  126: 
  127: : forward? ( target-addr -- target-addr false | true )
  128: 	dup there = ref? and dup
  129: 	IF nip THEN ;
  130: 
  131: :noname false TO ref-marker ; propper8 chained
  132: 
  133: variable ref-heap 0 ref-heap !
  134: 
  135: ' drop value std-resolver
  136: 
  137: : ref! ( flags/nr -- )
  138: \G stores a reference tag
  139:   \ get mem for tag
  140:   ref-tag-len allocate throw to ref-now 
  141:   \ build link
  142:   ref-heap @ ref-link !  ref-link ref-heap !
  143:   there ref-adr !
  144:   std-resolver ref-resolver ! 
  145:   ref-flag ! ;
  146: 
  147: : $ ( num -- address )
  148: \G makes a reference source with the next instruction
  149:   01ff and 0200 or ref! there  ;
  150: 
  151: : $: ( num -- )
  152: \G makes a reference target
  153:   01ff and 0a00 or ref! ;
  154: 
  155: : g$: ( num -- )
  156: \G makes a reference target for a global label
  157:   01ff and 0e00 or ref! ;
  158:   
  159: : g$ ( num -- addr )
  160: \G searches a global label and gets its address
  161:   01ff and 0e00 or
  162:   ref-heap BEGIN dup >r @ dup WHILE 2dup cell+ @ = 
  163:   IF nip to ref-now
  164:      ref-link @ r> !
  165:      ref-adr @ 
  166:      ref-now free throw EXIT THEN
  167:      r> drop
  168:   REPEAT 2drop -1 ABORT" could not resolve G label!" ;
  169: 
  170: : kill$: ( -- )
  171: \G deallocs the complete reference heap
  172:   ref-heap @ BEGIN dup WHILE dup @ swap free throw REPEAT drop 
  173:   0 ref-heap ! ;
  174: 
  175: : find$: ( adr nr -- )
  176:   0800 or
  177:   ref-heap 
  178:   BEGIN dup >r @ dup WHILE 2dup cell+ @ =
  179:   	IF nip to ref-now
  180:      	   r> drop
  181:            ref-resolve EXIT
  182: 	THEN
  183:      r> drop
  184:   REPEAT 2drop -1 ABORT" could not resolve label!" ;
  185: 
  186: : solve$
  187:   ref-heap dup >r @ 
  188:   BEGIN dup WHILE dup cell+ @ 0E00 and 0200 =
  189:    IF to ref-now
  190:       ref-link @ r@ !
  191:       ref-now >r
  192:       ref-adr @ ref-flag @ ( 01ff and ) find$:
  193:       r> to ref-now
  194:       ref-link ( dup >r ) @
  195:       ref-now free throw
  196:    ELSE 
  197:       r> drop
  198:       dup >r @
  199:    THEN
  200:   REPEAT r> drop drop kill$: ;
  201: 
  202: ' solve$ end-code8 chained
  203: 
  204: previous definitions

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>