File:  [gforth] / gforth / arch / mips / disasm.fs
Revision 1.3: download - view: text, annotated - select for diffs
Thu Jun 1 21:04:26 2000 UTC (23 years, 10 months ago) by anton
Branches: MAIN
CVS tags: HEAD
rewrote MIPS disassembler completely; now shares ints.fs file with asm.fs

\ disasm.fs	disassembler file (for MIPS R3000)
\
\ Copyright (C) 1995-97 Martin Anton Ertl, Christian Pirker
\
\ This file is part of RAFTS.
\
\	RAFTS 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
\	of the License, or (at your option) any later version.
\
\	This program 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 this program; if not, write to the Free Software
\	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

: disasm-illegal ( addr w -- )
    \ disassemble illegal instruction w at addr
    hex. ." , ( illegal inst ) " drop ;

: init-disasm-table ( n -- )
    \ initialize table with n entries with disasm-illegal
    0 ?do
	['] disasm-illegal ,
    loop ;

create opc-table $40 init-disasm-table \ top-level decode table
create funct-table $40 init-disasm-table \ special function table
create regimm-table $20 init-disasm-table \ regim instructions rt field
create copz-rs-table $20 init-disasm-table \ COPz instructions rs field
create copz-rt-table $20 init-disasm-table \ COPz instructions rt field
create cp0-table $40 init-disasm-table \ COP0 function table

\ fields

: disasm-op ( w -- u )
    26 rshift ;

: disasm-rs ( w -- u )
    21 rshift $1F and ;

: disasm-rt ( w -- u )
    16 rshift $1f and ;

: disasm-rd ( w -- u )
    11 rshift $1f and ;

: disasm-shamt ( w -- u )
    \ shift amount field
    6 rshift $1f and ;

: disasm-funct ( w -- u )
    $3f and ;

: disasm-copz ( w -- u )
    disasm-op 3 and ;

: disasm-imm ( w -- n )
    $ffff and dup 15 rshift negate 15 lshift or ;

: disasm-relative ( addr n -- w )
    \ compute printable form of relative address n relative to addr
    nip ( + ) ;

\ disassembler central decode cascade

: disasm-inst ( addr w -- )
    \G disassemble instruction w at addr (addr is used for computing
    \G branch targets)
    dup disasm-op cells opc-table + @ execute ;

: disasm-dump ( addr u -- ) \ gforth
    \G disassemble u aus starting at addr
    bounds u+do
	cr ." ( " i hex. ." ) " i i @ disasm-inst
	1 cells +loop ;

: disasm-special ( addr w -- )
    \ disassemble inst with opcode special
    dup disasm-funct cells funct-table + @ execute ;
' disasm-special 0 cells opc-table + !

: disasm-regimm ( addr w -- )
    \ disassemble regimm inst
    dup disasm-rt cells regimm-table + @ execute ;
' disasm-regimm 1 cells opc-table + !

: disasm-copz-rs ( addr w -- )
    \ disassemble inst with opcode COPz
    dup disasm-rs cells copz-rs-table + @ execute ;
' disasm-copz-rs $10 cells opc-table + !
' disasm-copz-rs $11 cells opc-table + !
' disasm-copz-rs $12 cells opc-table + !

: disasm-copz-rt ( addr w -- )
    \ disassemble inst with opcode COPz, rs=BC
    dup disasm-rt cells copz-rt-table + @ execute ;
' disasm-copz-rt $08 cells copz-rs-table + !

: disasm-cp0 ( addr w -- )
    \ disassemble inst with opcode COPz, rs=CO
    dup disasm-funct cells cp0-table + @ execute ;
' disasm-cp0 $10 cells copz-rs-table + !

\ disassemble various formats

: asm-op ( -- ) ;

: disasm-J-target ( addr w -- )
    \ print jump target
    $3ffffff and swap $fc000000 and or hex. ;

: asm-J-target ( u "inst" -- ; compiled code: addr w -- )
    \ disassemble jump inst with opcode u
    :noname POSTPONE disasm-J-target
    name POSTPONE sliteral POSTPONE type POSTPONE ;
    swap cells opc-table + ! ;

: disasm-I-rs,rt,imm ( addr w -- )
    dup disasm-rs .
    dup disasm-rt .
    disasm-imm disasm-relative . ;

: asm-I-rs,rt,imm ( u "name" -- ; compiled code: addr w -- )
    :noname POSTPONE disasm-I-rs,rt,imm
    name POSTPONE sliteral POSTPONE type POSTPONE ;
    swap cells opc-table + ! ;

: asm-rt ( -- ) ;

: disasm-I-rs,imm ( addr w -- )
    \ !! does not check for correctly set rt ( should be 0 )
    dup disasm-rs .
    disasm-imm disasm-relative . ;

: asm-I-rs,imm ( u1 u2 "name" -- ; compiled code: addr w -- )
    :noname POSTPONE disasm-I-rs,imm
    name POSTPONE sliteral POSTPONE type POSTPONE ;
    swap cells opc-table + ! ;

: disasm-rt,rs,imm ( addr w -- )
    dup disasm-rt .
    dup disasm-rs .
    disasm-imm .
    drop ;

: asm-I-rt,rs,imm ( u "name" -- ; compiled code: addr w -- )
    :noname POSTPONE disasm-rt,rs,imm
    name POSTPONE sliteral POSTPONE type POSTPONE ;
    swap cells opc-table + ! ;

: disasm-rt,imm ( addr w -- )
    dup disasm-rt .
    disasm-imm .
    drop ;

: asm-I-rt,imm ( u "name" -- ; compiled code: addr w -- )
    :noname POSTPONE disasm-rt,imm
    name POSTPONE sliteral POSTPONE type POSTPONE ;
    swap cells opc-table + ! ;

: disasm-rt,imm,rs ( addr w -- )
    dup disasm-rt .
    dup disasm-imm .
    dup disasm-rs .
    2drop ;

: asm-I-rt,offset,rs ( u "name" -- ; compiled code: addr w -- )
    :noname POSTPONE disasm-rt,imm,rs
    name POSTPONE sliteral POSTPONE type POSTPONE ;
    swap cells opc-table + ! ;

: disasm-rd,rt,sa ( addr w -- )
    dup disasm-rd .
    dup disasm-rt .
    dup disasm-shamt .
    2drop ;

: asm-special-rd,rt,sa ( u "name" -- ; compiled code: addr w -- )
    :noname POSTPONE disasm-rd,rt,sa
    name POSTPONE sliteral POSTPONE type POSTPONE ;
    swap cells funct-table + ! ;

: disasm-rd,rt,rs ( addr w -- )
    dup disasm-rd .
    dup disasm-rt .
    dup disasm-rs .
    2drop ;

: asm-special-rd,rt,rs ( u "name" -- ; compiled code: addr w -- )
    :noname POSTPONE disasm-rd,rt,rs
    name POSTPONE sliteral POSTPONE type POSTPONE ;
    swap cells funct-table + ! ;

: disasm-rs. ( addr w -- )
    dup disasm-rs .
    2drop ;

: asm-special-rs ( u "name" -- ; compiled code: addr w -- )
    :noname POSTPONE disasm-rs.
    name POSTPONE sliteral POSTPONE type POSTPONE ;
    swap cells funct-table + ! ;

: disasm-rd,rs ( addr w -- )
    dup disasm-rd .
    dup disasm-rs .
    2drop ;

: asm-special-rd,rs ( u "name" -- ; compiled code: addr w -- )
    :noname POSTPONE disasm-rd,rs
    name POSTPONE sliteral POSTPONE type POSTPONE ;
    swap cells funct-table + ! ;

: asm-special-nothing ( u "name" -- ; compiled code: addr w -- )
    :noname POSTPONE 2drop
    name POSTPONE sliteral POSTPONE type POSTPONE ;
    swap cells funct-table + ! ;

: disasm-rd. ( addr w -- )
    dup disasm-rd .
    2drop ;

: asm-special-rd ( u "name" -- ; compiled code: addr w -- )
    :noname POSTPONE disasm-rd.
    name POSTPONE sliteral POSTPONE type POSTPONE ;
    swap cells funct-table + ! ;

: disasm-rs,rt ( addr w -- )
    dup disasm-rs .
    dup disasm-rt .
    2drop ;

: asm-special-rs,rt ( u "name" -- ; compiled code: addr w -- )
    :noname POSTPONE disasm-rs,rt
    name POSTPONE sliteral POSTPONE type POSTPONE ;
    swap cells funct-table + ! ;

: disasm-rd,rs,rt ( addr w -- )
    dup disasm-rd .
    dup disasm-rs .
    dup disasm-rt .
    2drop ;

: asm-special-rd,rs,rt ( u "name" -- ; compiled code: addr w -- )
    :noname POSTPONE disasm-rd,rs,rt
    name POSTPONE sliteral POSTPONE type POSTPONE ;
    swap cells funct-table + ! ;

: asm-regimm-rs,imm ( u "name" -- )
    :noname POSTPONE disasm-I-rs,imm
    name POSTPONE sliteral POSTPONE type POSTPONE ;
    swap cells regimm-table + ! ;

: asm-copz-rt,offset,rs ( u "name" -- )
    \ ignore these insts, we disassemble using  asm-I-rt,offset,rs
    drop name 2drop ;

: asm-copz0 ( u "name" -- )
    :noname POSTPONE 2drop
    name POSTPONE sliteral POSTPONE type POSTPONE ;
    swap cells cp0-table + ! ;

$00 constant asm-copz-MF
$02 constant asm-copz-CF
$04 constant asm-copz-MT
$06 constant asm-copz-CT
$08 constant asm-copz-BC
$10 constant asm-copz-C0

$00 constant asm-copz-BCF
$01 constant asm-copz-BCT

: asm-rs ( -- ) ;

: disasm-rt,rd,z ( addr w -- )
    dup disasm-rt .
    dup disasm-rd .
    dup disasm-copz .
    2drop ;

: asm-copz-rt,rd ( u1 u2 "name" -- )
    drop :noname POSTPONE disasm-rt,rd,z
    name POSTPONE sliteral POSTPONE type POSTPONE ;
    swap cells copz-rs-table + ! ;

: disasm-I-imm ( addr w -- )
    disasm-imm disasm-relative . ;

: asm-copz-imm ( u1 u2 u3 "name" -- )
    drop nip :noname POSTPONE disasm-I-imm
    name POSTPONE sliteral POSTPONE type POSTPONE ;
    swap cells copz-rt-table + ! ;

include ./insts.fs

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