home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-11-30 | 25.4 KB | 1,059 lines | [TEXT/MSET] |
- (* *********
-
- \ PowerPC 601 Assembler
-
- \ Copyright 1993-1994 Xan Gregg All Rights Reserved
- \ Permission is granted for internal distribution by Creative Solutions, Inc.
-
- \ Permission also granted for Mops distribution. Mops mods made by
- \ Mike Hore.
-
- This is a basic PowerPC 601 assembler. It uses a Forth-like syntax,
- but the mnemonics and operand order is usually preserved. The exception
- is the branching instructions, which will be seldom used anyway since
- words like IF, and WHILE, are available. Often, duplicating identical
- parameters is not required, such as if the source and destination
- registers are the same.
-
- Examples Motorola Syntax Forth Syntax
- add. r1, r1, r2 r1 r2 add.,
- cmpi cr1, r3, 25 cr1 r3 25 cmpi,
- crnor crb1, crb1, crb4 crb1 crb4 crnor,
- --ALSO-- cr0 bGT cr1 bLT crnor,
- lfd fr1, 20(r2) fr1 20 r2 lfd,
- mtspr MQ, r3 MQ r3 mtspr,
- blt target target lt bc,
- blt- target hint target lt bc,
- bdnzl cr2, target cr2 target dnz bcl,
-
- Non-PowerPC instructions are not included.
-
- ***** *)
-
- decimal
-
-
- \ First, the Mops version of the utility words, and a few
- \ others we need as well:
-
- : DeferrErr true abort" DEFERRed word not set" ;
-
- : DEFER ['] deferrErr vect ;
- : IS postpone -> ; immediate
-
- : TOKEN@ @abs ;
- : TOKEN! reloc! ;
- : TOKEN, reloc, ;
-
- : NOT 0= ;
-
- : SCALE ( val cnt -- val' )
- dup 0< IF negate >> ELSE << THEN ;
-
- : HEX# postpone $ ; immediate
-
- : Lo2 $ 0000FFFF postpone literal postpone and ; immediate
- : Hi2 $ FFFF0000 postpone literal postpone and ; immediate
- : Hi2Lo 16 >> ;
-
- : ERROR" postpone abort" ; immediate
-
- : EVAL i >r evaluate r> -> i ; \ have to save & restore I till bug fixed
- : OFF false swap ! ;
- : ON true swap ! ;
- : BLWORD Mword ;
-
- : TOKEN.FOR state IF postpone ['] ELSE ' THEN ; immediate
-
- : RANGE within? ;
-
- : SIMM? ( n -- n b ) \ is this a signed immediate (16 bit) value?
- -32768 32767 within? ;
- : UIMM? ( n -- n b )
- 0 65535 within? ;
-
- : PSTRCPY ( addr1\addr2 -- )
- over c@ 1+ cmove ;
-
- : HOLD$ \ ( addr len -- )
- dup --> hld
- hld swap cmove ;
-
- : ALIGN4 \ pad with zero bytes till DP is 4-byte aligned
- DP
- 4 reserve \ just to ensure pad bytes are zero
- 3 + $ fffffffc and -> DP ;
-
- : #ALIGN4 \ ( n -- n' )
- 3 + $ fffffffc and ;
-
-
- : code_align PPC?
- IF CDP 4 erase CDP #align4 -> CDP
- ELSE align4
- THEN ;
-
-
- \ defer codeHere ' here is codeHere
- \ defer commaInstr ' , is commaInstr
-
- : codeHere PPC? IF CDP ELSE DP THEN ;
-
- \ note: code, (defined in Base) already looks at PPC? and does the right thing.
-
-
-
- 0 value opInstr \ instruction being assembled
-
- : OR>INSTR ( n -- ) opInstr or -> opInstr ;
-
- : ScaleOR>INSTR ( n\b -- ) scale or>instr ;
-
- : >RaField ( n -- ) 16 scaleOr>Instr ;
- : >RbField ( n -- ) 11 scaleOr>Instr ;
- : >RcField ( n -- ) 6 scaleOr>Instr ;
- : >RdField ( n -- ) 21 scaleOr>Instr ;
- : >RsField ( n -- ) 21 scaleOr>Instr ;
- : >LField ( n -- ) 21 scaleOr>Instr ;
- : >TOField ( n -- ) 21 scaleOr>Instr ;
- : >SRField ( n -- ) 16 scaleOr>Instr ;
- : >SHField ( n -- ) 11 scaleOr>Instr ;
- : >NBField ( n -- ) 11 scaleOr>Instr ;
- : >MBField ( n -- ) 6 scaleOr>Instr ;
- : >MEField ( n -- ) 1 scaleOr>Instr ;
- : >DispField ( n -- ) Lo2 or>Instr ;
- : >ImmField ( n -- ) Lo2 or>Instr ;
-
- hex# fa970000 constant RegisterID
- hex# fa870000 constant FRegisterID
- hex# fa770000 constant CRegisterID
- hex# fa670000 constant CBRegisterID
- hex# fa570000 constant SPRegisterID
- hex# fa470000 constant ModifierID
- hex# fa370000 constant ConditionID
-
- : MODIFIER ( value -- | create a register constant)
- ModifierID or constant ;
-
- : MODIFIER? ( [value] -- [value\true] | [false] )
- depth 0 > IF dup Hi2 ModifierID = ELSE false THEN ;
-
- : REGISTER ( value -- | create a register constant)
- RegisterID or constant ;
-
- : REGISTER# ( value -- n )
- Lo2 ;
-
- : REGISTER? ( [value] -- [value\true] | [false] )
- depth 0 > IF dup Hi2 RegisterID = ELSE false THEN ;
-
- : REGISTER#? ( [value] -- [value\true] | [false] )
- register? dup if swap register# swap then ;
-
- : NEEDREGISTER ( [value] -- )
- register? not error" EXPECTED A REGISTER" ;
-
- : NEEDREGISTER# ( [value] -- n )
- register#? not error" EXPECTED A REGISTER" ;
-
- : DECLAREREGISTERS ( -- )
- 32 0 DO
- i 0 <# 2dup #s " register R" hold$ 2drop #s #> eval
- LOOP ;
-
- : FREGISTER ( value -- | create a register constant)
- FRegisterID or constant ;
-
- : FREGISTER? ( [value] -- [value\true] | [false] )
- depth 0 > IF dup Hi2 FRegisterID = ELSE false THEN ;
-
- : FREGISTER#? ( [value] -- [value\true] | [false] )
- fregister? dup if swap register# swap then ;
-
- : NEEDFREGISTER ( [value] -- )
- fregister? not error" EXPECTED A FREGISTER" ;
-
- : NEEDFREGISTER# ( [value] -- )
- fregister#? not error" EXPECTED A FREGISTER" ;
-
- : DECLAREFREGISTERS ( -- )
- 32 0 DO
- i 0 <# 2dup #s " fregister FR" hold$ 2drop #s #> eval
- LOOP ;
-
- : CREGISTER ( value -- | create a register constant)
- CRegisterID or constant ;
-
- : CREGISTER? ( [value] -- [value\true] | [false] )
- depth 0 > IF dup Hi2 CRegisterID = ELSE false THEN ;
-
- : CREGISTER#? ( [value] -- [value\true] | [false] )
- cregister? dup if swap register# swap then ;
-
- : NEEDCREGISTER ( [value] -- )
- cregister? not error" EXPECTED A CREGISTER" ;
-
- : DECLARECREGISTERS ( -- )
- 8 0 DO
- i 0 <# 2dup #s " cregister CR" hold$ 2drop #s #> eval
- LOOP ;
-
- : CBREGISTER ( value -- | create a register constant)
- CBRegisterID or constant ;
-
- : CBREGISTER? ( [value] -- [value\true] | [false] )
- depth 0 > IF dup Hi2 CBRegisterID = ELSE false THEN ;
-
- : CBREGISTER#? ( [value] -- [value\true] | [false] )
- cbregister? dup if swap register# swap then ;
-
- : NEEDCBREGISTER ( [value] -- )
- cbregister? not error" EXPECTED A CBREGISTER" ;
-
- : DECLARECBREGISTERS ( -- )
- 32 0 DO
- i 0 <# 2dup #s " cbregister CRB" hold$ 2drop #s #> eval
- LOOP ;
-
- : SPREGISTER ( value -- | create a register constant)
- dup 31 and 5 scale swap -5 scale or SPRegisterID or constant ;
-
- : SPREGISTER? ( [value] -- [value\true] | [false] )
- depth 0 > IF dup Hi2 SPRegisterID = ELSE false THEN ;
-
- : NEEDSPREGISTER ( [value] -- )
- spregister? not error" EXPECTED An SPREGISTER" ;
-
- : CONDITION ( value -- | create a condition constant)
- conditionID or
- constant ;
-
- : CONDITION? ( [value] -- [value\true] | [false] )
- depth 0 > IF dup Hi2 conditionID = ELSE false THEN ;
-
- : NEEDCONDITION ( [value] -- )
- condition? not error" EXPECTED A CONDITION" ;
-
- : MODIFIERVALUE ( value -- n )
- Lo2 ;
-
- : CONDITIONVALUE ( value -- n )
- Lo2 ;
-
- \ branchHint is a one-shot set by 'hint' and cleared by the next branch instr.
- variable branchHint
- branchHint off
-
- \ ASSEMBLER.WORDS
-
- : hint branchHint on ;
-
- DeclareRegisters
- DeclareFRegisters
- DeclareCRegisters
- DeclareCBRegisters
-
- 0 SPRegister MQ
- 1 SPRegister XER
- 4 SPRegister RTCU
- 5 SPRegister RTCL
- 6 SPRegister DEC
- 8 SPRegister LR
- 9 SPRegister CTR
-
- : bLT ( [cr] -- crb ) CRegister#? not IF 0 THEN 4* CBRegisterID or ;
- : bGT ( [cr] -- crb ) CRegister#? not IF 0 THEN 4* 1+ CBRegisterID or ;
- : bEQ ( [cr] -- crb ) CRegister#? not IF 0 THEN 4* 2+ CBRegisterID or ;
- : bSO ( [cr] -- crb ) CRegister#? not IF 0 THEN 4* 3+ CBRegisterID or ;
-
- create condArea 10 allot
-
- : COND$ condArea count ;
-
-
- : COND3 ( bit#\pos? -- )
- blword condArea pstrcpy
- IF hex# 180 ELSE hex# 080 THEN or
- dup 0 <# cond$ hold$ " condition " hold$ #s #> eval
- hex# f7f and
- dup ( 1+) 0 <# cond$ hold$ " condition dnz" hold$ #s #> eval
- hex# 040 or 0 <# cond$ hold$ " condition dz" hold$ #s #> eval
- ;
-
- 0 1 cond3 lt
- 1 1 cond3 gt
- 2 1 cond3 eq
- 3 1 cond3 so
- 4 1 cond3 un
- 0 0 cond3 nl
- 1 0 cond3 ng
- 2 0 cond3 ne
- 3 0 cond3 ns
- 4 0 cond3 nu
- 0 0 cond3 ge
- 1 0 cond3 le
- hex# 200 condition dnz
- hex# 240 condition dz
- hex# 280 condition tr
-
- 1 modifier LONG \ for cmp instruction
- 0 modifier WD \ for cmp instruction ** note - can't use WORD
-
- \ LOCAL.WORDS
-
- \ GetDAB ( dreg\[areg]\[breg]\tester -- | inserts D, A, and B regs into opInstr)
- \ A and B are optional
-
- : GetDAB ( d a b ) { tester \ d a b -- } \ inserts D, A, and B regs into opInstr)
- \ 0 0 0 locals| d a b tester |
-
- tester execute not error" expected a register"
- -> b
- tester execute not IF \ 1 register: d,d,d
- b -> a
- a -> d
- ELSE
- -> a
- tester execute IF \ 3 registers: d,a,b
- -> d
- ELSE \ 2 registers: d,d,a
- a -> d
- THEN
- THEN
- d >RdField a >RaField b >RbField ;
-
- : GETRDAB ( dreg\[areg]\[breg] -- )
- token.for register#? getDAB ;
-
- : GETFRDAB ( dreg\[areg]\[breg] -- )
- token.for fregister#? getDAB ;
-
- : getCRBdab ( dreg\[areg]\[breg] -- )
- token.for cbregister#? getDAB ;
-
- : ?SIMM ( n -- )
- simm? nip not error" EXPECTED A SIMM" ;
-
- : ?UIMM ( n -- )
- 0 65535 range nip not error" EXPECTED A UIMM" ;
-
- \ GETDAIMM ( dreg\[areg]\simm\tester -- | inserts D, and A regs and SIMM into opInstr)
- \ A is optional
-
- : GETDAIMM ( d [a] ) { simm tester \ d a -- }
-
- \ 0 0 locals| d a tester simm |
-
- simm tester execute
- register#? not error" expected a register"
- -> a
- register#? not IF a THEN -> d
- d >RdField a >RaField simm >ImmField ;
-
- : GETRDASIMM ( dreg\[areg]\simm -- )
- token.for ?simm GetDAImm ;
-
- : GETRDAUIMM ( dreg\[areg]\simm -- )
- token.for ?uimm GetDAImm ;
-
- : GETRDAIMM ( dreg\[areg]\imm -- )
- token.for drop GetDAImm ;
-
- \ GETDA ( dreg\[areg]\tester -- | inserts D and A regs into opInstr)
- \ A is optional
- \ 0 0 locals| d a tester |
-
- : GETDA ( d [a] ) { tester \ d a -- }
-
- tester execute not error" expected a register"
- -> a
- tester execute not IF a THEN -> d
- d >RdField a >RaField ;
-
- : GETRDA ( dreg\[areg] -- )
- token.for register#? GetDA ;
-
- : GETRASBIMM ( [areg]\sreg\[breg]|[imm] -- )
- register#? IF >RbField ELSE >ImmField THEN
- needRegister# dup >R >RsField
- register#? IF R> drop ELSE R> THEN >RaField ;
-
- : GETRASB ( [areg]\sreg\breg -- )
- needRegister# >RbField
- needRegister# dup >R >RsField
- register#? IF R> drop ELSE R> THEN >RaField ;
-
- : GETRASIMM ( [areg]\sreg\imm -- )
- dup ?uimm
- >ImmField
- needRegister# dup >R >RsField
- register#? IF R> drop ELSE R> THEN >RaField ;
-
- : GETCRLAB ( [crReg]\[L]\areg\breg -- )
- needRegister# >RbField
- needRegister# >RaField
- modifier? IF ModifierValue >LField THEN
- cregister#? if 23 ScaleOR>INSTR then ;
-
- : GETCRLAIMM ( [crReg]\[L]\areg\imm -- )
- dup ?simm
- >ImmField
- needRegister# >RaField
- modifier? IF ModifierValue >LField THEN
- cregister#? if 23 ScaleOR>INSTR then ;
-
- : GETCRFAB ( [crReg]\areg\breg -- )
- needFRegister# >RbField
- needFRegister# >RaField
- cregister#? if 23 ScaleOR>INSTR then ;
-
- : GETRAB ( areg\breg -- )
- needRegister# >RbField
- needRegister# >RaField ;
-
- : GETRAS ( areg\[sreg] -- ) { \ s -- }
- \ needRegister# locals| S |
- needRegister# -> s
- s >RsField
- register#? not IF s THEN >RaField ;
-
- : GETFRDB ( dfreg\[bfreg] -- ) { \ b -- }
- \ needFRegister# locals| B |
- needFRegister# -> b
- b >RbField
- fregister#? not IF b THEN >RdField ;
-
- : GetNull ( -- )
- ;
-
- : GetRsab ( [sreg]\areg\breg -- )
- needRegister# >RbField
- needRegister# dup >R >RaField
- register#? IF R> drop ELSE R> THEN >RsField ;
-
- : GetCRds ( CRd\CRs -- )
- needCRegister register# 18 ScaleOR>INSTR
- needCRegister register# 23 ScaleOR>INSTR ;
-
- : GetCRd ( CRd -- )
- needCRegister register# 23 ScaleOR>INSTR ;
-
- : GetRd ( Rd -- )
- needRegister# >RdField ;
-
- : GetRdSPR ( Rd\SPR -- )
- needSPRegister register# 11 ScaleOR>INSTR
- needRegister# >RdField ;
-
- : GetRdSR ( Rd\SR -- )
- >SRField
- needRegister# >RdField ;
-
- : GetRdb ( [Rd]\Rb -- )
- needRegister# dup >R >RbField
- register#? IF R> drop ELSE R> THEN >RdField ;
-
- : getCRMRs ( CRM\Rs -- )
- needRegister# >RsField
- 255 and 12 ScaleOR>INSTR ; \ bug fixed 25-Aug-94 via msg from xg
-
- : getCRBd ( CRBd -- )
- needCBRegister register# >RdField ;
-
- : getFMFrb ( FM\FRb -- )
- needFRegister# >RbField
- 255 and 17 ScaleOR>INSTR ;
-
- : getCRdBImm ( CRd\Imm -- )
- 15 and 12 ScaleOR>INSTR
- needCRegister register# 23 ScaleOR>INSTR ;
-
- : GetRs ( sreg -- )
- needRegister# >RsField ;
-
- : GetSPRRs ( SPR\Rs -- )
- needRegister# >RsField
- needSPRegister register# 11 ScaleOR>INSTR ;
-
- : getSRRs ( SR\Rs -- )
- needRegister# >RsField
- 15 and >SRField ;
-
- : getRsb ( [Rs]\Rb -- )
- needRegister# dup >R >RbField
- register#? IF R> drop ELSE R> THEN >RsField ;
-
- : getRasSHMBME ( [Ra]\Rs\SH\MB\ME -- )
- 31 and >MEField
- 31 and >MBField
- 31 and >SHField
- needRegister# dup >R >RsField
- register#? IF R> drop ELSE R> THEN >RaField ;
-
- : getRasbMBME ( [Ra]\Rs\Rb\MB\ME -- )
- 31 and >MEField
- 31 and >MBField
- needRegister# >SHField
- needRegister# dup >R >RsField
- register#? IF R> drop ELSE R> THEN >RaField ;
-
- : getRasSH ( [Ra]\Rs\SH -- )
- 31 and >SHField
- needRegister# dup >R >RsField
- register#? IF R> drop ELSE R> THEN >RaField ;
-
- : getRsaDisp ( Rs\[disp\]Ra -- )
- needRegister# >RaField
- simm? if >DispField then
- needRegister# >RsField ;
-
- : getFRsRaDisp ( FRs\[disp\]Ra -- )
- needRegister# >RaField
- simm? if >DispField then
- needFRegister# >RsField ;
-
- : getFRsRab ( FRs\Ra\Rb -- )
- needRegister# >RbField
- needRegister# >RaField
- needFRegister# >RsField ;
-
- : getRsaNB ( [Ra]\Rs\NB -- )
- 31 and >NBField
- needRegister# dup >R >RaField
- register#? IF R> drop ELSE R> THEN >RsField ;
-
-
- : getRb ( Rb -- )
- needRegister# >RbField ;
-
- : getTORab ( TO\Ra\Rb -- )
- needRegister# >RbField
- needRegister# >RaField
- 31 and >TOField ;
-
- : getTORaSImm ( TO\Ra\Simm -- )
- dup ?simm >ImmField
- needRegister# >RaField
- 31 and >TOField ;
-
- : getFRdRaDisp ( FRd\[disp\]Ra -- )
- needRegister# >RaField
- simm? if >DispField then
- needFRegister# >RdField ;
-
- : getFRdRab ( FRd\Ra\Rb -- )
- needRegister# >RbField
- needRegister# >RaField
- needFRegister# >RdField ;
-
- : getRdaDisp ( Rd\[disp\]Ra -- )
- needRegister# >RaField
- simm? if >DispField then
- needRegister# >RdField ;
-
- : getRdaNB ( Rd\Ra\nb -- )
- 31 and >NBField
- needRegister# >RaField
- needRegister# >RdField ;
-
- : getFRdacb ( [FRd]\FRa\FRc\FRb -- )
- needFRegister# >RbField
- needFRegister# >RcField
- needFRegister# dup >R >RaField
- fregister#? IF R> drop ELSE R> THEN >RdField ;
-
- : getFRdac ( [FRd]\FRa\FRc -- )
- needFRegister# >RcField
- needFRegister# dup >R >RaField
- fregister#? IF R> drop ELSE R> THEN >RdField ;
-
-
- : checkAddress ( addr\numBits -- addr )
- over 3 and error" INVALID ADDRESS - NOT MULTIPLE OF 4"
- 1 swap 1- scale dup negate swap 1-
- range not error" INVALID ADDRESS - OUT OF RANGE" ;
-
- : ?hint \ set the branch bit if requested by the one-shot
- branchHint @ if
- branchHint off
- 1 21 scaleOr>Instr
- then ;
-
- : getAbsAddr
- 26 checkAddress
- \ hex# 3FF,FFFC and or>Instr ?hint ;
- hex# 3FFFFFC and or>Instr ?hint ;
-
- : getRelAddr ( addr -- )
- codehere - getAbsAddr ;
-
- : getBOBI ( [crreg]\[cond] -- )
- condition? IF
- conditionValue 16 ScaleOr>Instr
- ELSE
- hex# 280 16 ScaleOr>Instr \ branch always if no condition
- THEN
- cregister#? IF
- 18 ScaleOr>Instr
- THEN ?hint ;
-
- : getUncondBOBI ( -- )
- hex# 280 16 ScaleOr>Instr ; \ branch always
-
-
- : getBOBIAddr ( addr\[cond]\[cond] -- )
- condition? IF
- conditionValue 16 ScaleOr>Instr
- ELSE
- hex# 280 16 ScaleOr>Instr \ branch always if no condition
- THEN
- opInstr 2 and not IF codehere - THEN
- 13 checkAddress hex# fffc and or>Instr
- cregister#? IF
- 18 ScaleOr>Instr
- THEN ?hint ;
-
- \ -------------------------------------------------------
- : OP ( asm instruction defining word )
- \ find dup -found >R
- \ create ( opcode1\opcode2 -- ) swap 26 scale or , R> token,
-
- Mword find NIF ." aauuggghhh!!" abort THEN
- >r
- <builds ( opcode1\opcode2 -- ) swap 26 scale or , r> token,
-
- does> ( pfa -- | lays down instruction )
- dup @ -> opInstr
- 4+ token@ execute
- opInstr code, ;
-
- create OPCODEArea 10 allot
- : OPCODE$ opcodeArea count ;
-
- create GETTERAREA 20 allot
- : GETTER$ getterArea count ;
-
- : DEFININGTEXT ( n1 n2 -- 0 | called from inside <# #> )
- \ mh's note - we take care of converting the numbers to doubles here.
-
- 0 swap 0
- opcode$ hold$ BL hold getter$ hold$ " OP " hold$ #S BL hold 2drop #s ;
-
- \ : evaluate.string ( addr -- )
- \ cr dup count type
- \ evaluate.string
- \ 40 >col here 14 .r ;
-
- : OPo. ( opcode1\opcode2 -- super asm instruction defining word )
- blword getterArea pstrcpy
- blword opcodeArea pstrcpy
- 2* 2dup <# " ," hold$ definingText #> eval
- 2dup 1+ <# " .," hold$ definingText #> eval
- 2dup 1024 + <# " o," hold$ definingText #> eval
- 1025 + <# " o.," hold$ definingText #> eval
- ;
-
- : OP. ( opcode1\opcode2 -- super asm instruction defining word )
- blword getterArea pstrcpy
- blword opcodeArea pstrcpy
- 2* 2dup <# " ," hold$ definingText #> eval
- 1+ <# " .," hold$ definingText #> eval
- ;
-
- \ ASSEMBLER.WORDS
-
-
- 31 266 OPo. getRdab add
- 31 10 OPo. getRdab addc
- 31 138 OPo. getRdab adde
- 14 0 OP getRdaSimm addi,
- 12 0 OP getRdaSimm addic,
- 13 0 OP getRdaSimm addic.,
- 15 0 OP getRdaSimm addis,
- 31 234 OPo. getRda addme
- 31 202 OPo. getRda addze
- 31 28 OP. getRasb and
- 31 60 OP. getRasb andc
- 28 0 OP getRasImm andi.,
- 29 0 OP getRasImm andis.,
-
- ( ** branch instructions ** )
- 18 0 OP getRelAddr b,
- 18 2 OP getAbsAddr ba,
- 18 1 OP getRelAddr bl,
- 18 3 OP getAbsAddr bla,
- 16 0 OP getBOBIAddr bc,
- 16 2 OP getBOBIAddr bca,
- 16 1 OP getBOBIAddr bcl,
- 16 3 OP getBOBIAddr bcla,
- 19 1056 OP getBOBI bcctr,
- 19 1057 OP getBOBI bcctrl,
- 19 32 OP getBOBI bclr,
- 19 33 OP getBOBI bclrl,
- 19 1056 OP getUncondBOBI bctr,
- 19 1057 OP getUncondBOBI bctrl,
- 19 32 OP getUncondBOBI blr,
- 19 33 OP getUncondBOBI blrl,
-
- 31 0 OP getCrLAB cmp,
- 11 0 OP getCrLAImm cmpi,
- 31 64 OP getCrLAB cmpl,
- 10 0 OP getCrLAImm cmpli,
- 31 26 OP. getRas cntlzw
- 19 514 OP getCRBdab crand,
- 19 258 OP getCRBdab crandc,
- 19 578 OP getCRBdab creqv,
- 19 450 OP getCRBdab crnand,
- 19 66 OP getCRBdab crnor,
- 19 898 OP getCRBdab cror,
- 19 834 OP getCRBdab crorc,
- 19 386 OP getCRBdab crxor,
- 31 172 OP getRab dcbf,
- 31 940 OP getRab dcbi,
- 31 108 OP getRab dcbst,
- 31 556 OP getRab dcbt,
- 31 492 OP getRab dcbtst,
- 31 2028 OP getRab dcbz,
- 31 491 OPo. getRdab divw
- 31 459 OPo. getRdab divwu
- 31 620 OP getRdab eciwx,
- 31 876 OP getRdab ecowx,
- 31 1708 OP getNull eieio,
- 31 284 OP. getRasb eqv
- 31 954 OP. getRas extsb
- 31 922 OP. getRas extsh
-
- 63 264 OP. getFRdb fabs
- 63 21 OP. getFRdab fadd
- 59 21 OP. getFRdab fadds
- 63 64 OP getCRFab fcmpo,
- 63 0 OP getCRFab fcmpu,
- 63 14 OP. getFRdb fctiw
- 63 15 OP. getFRdb fctiwz
- 63 18 OP. getFRdab fdiv
- 59 18 OP. getFRdab fdivs
- 63 29 OP. getFRdacb fmadd
- 59 29 OP. getFRdacb fmadds
- 63 72 OP. getFRdb fmr
- 59 28 OP. getFRdacb fmsub
- 59 28 OP. getFRdacb fmsubs
- 63 25 OP. getFRdac fmul
- 59 25 OP. getFRdac fmuls
- 63 136 OP. getFRdb fnabs
- 63 40 OP. getFRdb fneg
- 63 31 OP. getFRdacb fnmadd
- 59 31 OP. getFRdacb fnmadds
- 63 30 OP. getFRdacb fnmsub
- 59 30 OP. getFRdacb fnmsubs
- 63 12 OP. getFRdb frsp
- 63 20 OP. getFRdab fsub
- 59 20 OP. getFRdab fsubs
-
- 31 1964 OP getRab icbi,
- 19 300 OP getNull isync,
- 34 0 OP getRdaDisp lbz,
- 35 0 OP getRdaDisp lbzu,
- 31 238 OP getRdab lbzux,
- 31 174 OP getRdab lbzx,
- 50 0 OP getFRdRaDisp lfd,
- 51 0 OP getFRdRaDisp lfdu,
- 31 1262 OP getFRdRab lfdux,
- 31 1198 OP getFRdRab lfdx,
- 48 0 OP getFRdRaDisp lfs,
- 49 0 OP getFRdRaDisp lfsu,
- 31 1134 OP getFRdRab lfsux,
- 31 1070 OP getFRdRab lfsx,
- 31 1198 OP getFRdRab lfdx,
- 42 0 OP getRdaDisp lha,
- 43 0 OP getRdaDisp lhau,
- 31 750 OP getRdab lhaux,
- 31 686 OP getRdab lhax,
- 31 1580 OP getRdab lhbrx,
- 40 0 OP getRdaDisp lhz,
- 41 0 OP getRdaDisp lhzu,
- 31 622 OP getRdab lhzux,
- 31 558 OP getRdab lhzx,
- 46 0 OP getRdaDisp lmw,
- 31 1194 OP getRdaNb lswi,
- 31 1066 OP getRdab lswx,
- 31 40 OP getRdab lwarx,
- 31 1068 OP getRdab lwbrx,
- 32 0 OP getRdaDisp lwz,
- 33 0 OP getRdaDisp lwzu,
- 31 110 OP getRdab lwzux,
- 31 46 OP getRdab lwzx,
-
- 19 0 OP getCRds mcrf,
- 63 128 OP getCRds mcrfs,
- 31 1024 OP getCRd mcrxr,
- 31 38 OP getRd mfcr,
- 63 583 OP. getRd mffs
- 31 166 OP getRd mfmsr,
- 31 678 OP getRdSPR mfspr,
- 31 1190 OP getRdSR mfsr,
- 31 1318 OP getRdb mfsrin,
- 31 288 OP getCRMRs mtcrf,
- 63 70 OP. getCRBd mtfsb0
- 63 38 OP. getCRBd mtfsb1
- 31 711 OP. getFMFrb mtfsf
- 63 134 OP. getCRdBImm mtfsfi
- 31 292 OP getRs mtmsr,
- 31 934 OP getSPRRs mtspr,
- 31 420 OP getSRRs mtsr,
- 31 484 OP getRsb mtsrin,
- 31 75 OP. getRdab mulhw
- 31 11 OP. getRdab mulhwu
- 31 235 OPo. getRdab mullw
- 7 0 OP getRdaSImm mulli,
- 31 476 OP. getRasb nand
- 31 104 OPo. getRda neg
- 31 124 OP. getRasb nor
- 31 444 OP. getRasb or
- 31 412 OP. getRasb orc
- 24 0 OP getRasImm ori,
- 25 0 OP getRasImm oris,
- 19 100 OP getNull rfi,
- 20 0 OP. getRasSHMBME rlwimi
- 21 0 OP. getRasSHMBME rlwinm
- 23 0 OP. getRasbMBME rlwnm
- 17 2 OP getNull sc,
-
- 31 24 OP. getRasb slw
- \ 31 794OP. getRasb srad
- 31 792 OP. getRasb sraw
- 31 824 OP. getRasSH srawi
- \ 31 539OP. getRasb srd
- 31 536 OP. getRasb srw
- 38 0 OP getRsaDisp stb,
- 39 0 OP getRsaDisp stbu,
- 31 494 OP getRsab stbux,
- 31 430 OP getRsab stbx,
- 54 0 OP getFRsRaDisp stfd,
- 55 0 OP getFRsRaDisp stfdu,
- 31 1518 OP getFRsRab stfdux,
- 31 1454 OP getFRsRab stfdx,
- 52 0 OP getFRsRaDisp stfs,
- 53 0 OP getFRsRaDisp stfsu,
- 31 1390 OP getFRsRab stfsux,
- 31 1326 OP getFRsRab stfsx,
- 44 0 OP getRsaDisp sth,
- 31 1836 OP getRsab sthbrx,
- 45 0 OP getRsaDisp sthu,
- 31 878 OP getRsab sthux,
- 31 814 OP getRsab sthx,
- 47 0 OP getRsaDisp stmw,
- 31 1450 OP getRsaNB stswi,
- 31 1322 OP getRsab stswx,
- 36 0 OP getRsaDisp stw,
- 31 1324 OP getRsab stwbrx,
- 31 301 OP getRsab stwcx.,
- 37 0 OP getRsaDisp stwu,
- 31 366 OP getRsab stwux,
- 31 302 OP getRsab stwx,
- 31 40 OPo. getRdab subf
- 31 8 OPo. getRdab subfc
- 31 136 OPo. getRdab subfe
- 08 0 OP getRdaSImm subfic,
- 31 232 OPo. getRda subfme
- 31 200 OPo. getRda subfze
- 31 1196 OP getNull sync,
- 31 612 OP getRb tlbie,
- 31 8 OP getTORab tw,
- 03 0 OP getTORaSImm twi,
- 31 316 OP. getRasb xor
- 26 0 OP getRasImm xori,
- 27 0 OP getRasImm xoris,
-
- \ Assembler Macro Definitions
-
- \ Branching macros
-
- : bcPatch ( instr addr\dest addr )
- over - 13 checkAddress
- hex# 0000FFFC and over @ hex# FFFF0003 and or swap ! ;
-
- : bPatch ( instr addr\dest addr )
- over - 24 checkAddress
- hex# 03FFFFFC and over @ hex# FC000003 and or swap ! ;
-
- : invertCondition ( condition -- condition' )
- dup hex# 200 and 0= IF \ make sure it uses conditions
- hex# 100 xor \ flip BO[1]
- THEN ;
-
- : if, ( condition -- addr\2 )
- invertCondition codehere swap bc,
- codehere 4- 2 ;
-
- : else, ( addr\2 -- addr\3 )
- 2 ?pairs codehere 4+ bcPatch
- codehere b,
- codehere 4- 3 ;
-
- : then, ( [addr\2] or [addr\3] -- )
- dup 3 = IF
- 3 ?pairs codehere bpatch
- ELSE
- 2 ?pairs codehere bcPatch
- THEN ;
-
- : begin, ( -- addr\1 )
- codehere 1 ;
-
- : while, ( condition -- addr\4 )
- if, 2+ ;
-
- : bcBackwhiles ( [addr\4]* -- )
- begin
- dup 4 =
- while
- drop codehere 4+ bcPatch
- repeat ;
-
- : again, ( addr\1[\addr\4]* -- )
- bcBackwhiles
- 1 ?pairs
- b, ;
-
- : repeat, ( addr\1[\addr\4]* -- )
- again, ;
-
- : until, ( addr\1[\addr\4]*\condition -- )
- >R bcBackwhiles
- 1 ?pairs
- R> invertCondition bc, ;
-
- \ these are simplified mnemonics from PowerPC manual
-
- : nop, ( -- ) r0 r0 r0 ori, ;
-
- : li, ( rA\SIMM -- | load immediate ) r0 swap addi, ;
- : lis, ( rA\SIMM -- | load immediate shifted ) r0 swap addis, ;
- : lli, ( rA\SLIMM -- | load long immediate )
- dup 0=
- IF li,
- ELSE
- 2dup extend dup \ rA\SLIMM\rA\simm\simm
- IF li,
- dup Hi2Lo swap hex# 8000 and IF \ sign bit set in lo 16 bits?
- 1+ Lo2
- THEN
- dup IF extend addis, ELSE 2drop THEN
- ELSE \ lo half is 0
- 2drop Hi2Lo extend lis,
- THEN
- THEN ;
-
- (* ***
- old versions:
-
- : li, ( rA\SIMM -- | load immediate ) r0 swap addi, ;
- : lis, ( rA\SIMM -- | load immediate shifted ) r0 swap addis, ;
- : lli, ( rA\SLIMM -- | load long immediate )
- 2dup extend li,
- dup Hi2Lo swap hex# 8000 and IF \ sign bit set in lo 16 bits?
- 1+ Lo2
- THEN
- ?dup IF extend addis, ELSE drop THEN ;
-
- *** *)
-
- : lui, ( rA\SIMM -- | load immediate ) lli, ;
- : la, ( rD\SIMM\rA -- | load address ) swap addi, ;
- : move, ( rA\rS -- ) dup or, ;
- : move., ( rA\rS -- ) dup or., ;
- : not, ( rA\rS -- ) dup nor, ;
- : not., ( rA\rS -- ) dup nor., ;
- : subi, ( rA\SIMM -- ) negate addi, ;
- : slwi, ( rA\rS\n -- ) 0 over 31 swap - rlwinm, ;
- : srwi, ( rA\rS\n -- ) 32 over - swap 31 rlwimi, ;
-
- : mtlr, ( rA -- ) lr swap mtspr, ;
- : mflr, ( rA -- ) lr mfspr, ;
- : mtctr, ( rA -- ) ctr swap mtspr, ;
- : mfctr, ( rA -- ) ctr mfspr, ;
- : clr, ( rA -- ) dup dup subf, ;
-
- \ Some Forth macros
-
- : rOSSP r1 ; \ Operating system stack pointer
- : rTOC r2 ; \ table of contents pointer
- : rTOS r13 ; \ top of data stack value
- : rDSP r14 ; \ data stack pointer
- : rRSP r15 ; \ return stack pointer
- : rUP r16 ; \ user area pointer
- : rLFP r17 ; \ local frame pointer
- : rCBP r18 ; \ code base pointer
- : rDBP r19 ; \ data base pointer
- : rDoLimit r20 ;
- : rDoIndex r21 ;
-
- \ Note: R11, R12, CR6, & CR7 are designated as scratch registers by Apple
-
- : rX r11 ;
- : rY r12 ;
- : crX cr6 ;
- : crY cr7 ;
-
- \ r0 is also scratch but must be used carefully as it is special in some
- \ instructions
-
- : put, ( reg -- ) rtos swap move, ;
- : pushtos, ( -- ) rtos -4 rdsp stwu, ;
- : push, ( reg -- ) pushtos, put, ;
-
- : get, ( reg -- ) rtos move, ;
- : poptos, ( -- ) rtos 0 rdsp lwz, rdsp 4 addi, ;
- : pop, ( reg -- ) get, poptos, ;
-
- : tst, ( reg -- ) 0 cmpi, ;
-
- : rts, ( -- ) bclr, ;
- : next, ( address interpreter )
- rts, ;
-
-
- decimal
-
- false value pasm_done?
-
-
- : FIND_IN_PASM \ ( s255 -- cfa true | -- s255 false )
- find: pasmMod ;
-
-
- : ENTERCODE \ begin assembly outside of a colon definition
- lock: pasmMod
- ['] find_in_pasm -> extraFind \ look up words in pasm first. Exclude
- \ locals and class stuff for the duration
- false -> pasm_done?
- code_align
- ;
-
-
- \ :PPC_CODE begins a code definition. We set up a header specifying
- \ no named parms/locals and 2 results. This means that the top 2 stack
- \ cells will be in r4 and r3 on both entry and exit, which keeps things
- \ simple.
-
- : :PPC_CODE
- ppc_header
- $ BE00 codeW, \ handler code for PPC colon defns
- $ 0200 codeW, \ no named parms/locals, 2 results
- entercode
- BEGIN
- topfile -> source-ID (Frefill) IF interpret THEN
- pasm_done?
- UNTIL ;
-
-
- : ;PPC_CODE
- 0 -> extraFind
- unlock: pasmMod
- true -> pasm_done?
- ?exec reveal
- ;
-
-
- // disAsm
-