public inbox for cgen@sourceware.org
 help / color / mirror / Atom feed
* Re: Again: variable width instructions
@ 2003-02-10  0:56 Doug Evans
  2003-02-11 13:42 ` Manuel Kessler
  0 siblings, 1 reply; 4+ messages in thread
From: Doug Evans @ 2003-02-10  0:56 UTC (permalink / raw)
  To: Manuel Kessler; +Cc: cgen

Hi.

Regarding the fr30 example:

; test file for ldi32
        ldi:32 $0x80000000, r0
        nop
        ldi:32 $0x00000000, r1
        nop
        ldi:32 $0xffffffff, r2
        nop
        ldi:32 $0x7fffffff, r3
        nop
.end

Things might actually be working ok, depending upon whether or not
$0x80000000, etc. are valid symbols.  What's happening is that
gas is interpreting them as symbols ($ doesn't prefix constants in
fr30 assembler).  If you had included -r in the arguments to objdump
you would have seen the following.  Live and learn I guess. :-)

00000000 <foo>:
   0:	9f 80 00 00 	ldi:32 0x0,r0
   4:	00 00 
			0: R_FR30_48	$0x80000000
   6:	9f a0       	nop
   8:	9f 81 00 00 	ldi:32 0x0,r1
   c:	00 00 
			8: R_FR30_48	$0x00000000
   e:	9f a0       	nop
  10:	9f 82 00 00 	ldi:32 0x0,r2
  14:	00 00 
			10: R_FR30_48	$0xffffffff
  16:	9f a0       	nop
  18:	9f 83 00 00 	ldi:32 0x0,r3
  1c:	00 00 
			18: R_FR30_48	$0x7fffffff
  1e:	9f a0       	nop

Regarding problems specifying ciscy fields in m16c.cpu, Jan is right.
You (probably) want to use the full form of define-ifield for these.
It's unfortunate that I didn't create a shorthand version of the
full form of define-ifield, I think its absence has led to some confusion.
E.g. You don't need #lsb0 = #f, it just makes the abbreviated short forms
dnf and df [sic (*1)] work better.

I went to savannah.nongnu.org and checked out and built an m16c toolchain
(but using the m16c.cpu file you included in your message).

I can see some of the problems you're having.  For example,

	neg.b 4[a0]

disassembles to

   0:	a2 2f 04 42 	*unknown*

but it's only a 3 byte insn.

You really do want to use the proper values of 8 for base-insn-size, etc.

  (default-insn-bitsize 8)
  (base-insn-bitsize 8)
  (default-insn-word-bitsize ???)

Off the top of my head I dunno what's a good value for
default-insn-word-bitsize for the m16c.

Given that base-insn-bitsize is 8 you'll want to use the full form of
define-ifield, or the macros that are in your m16.cpu file: dif and dnif (*2).

There's one more problem though.  Cgen current doesn't support ifields
with constant values beyond base-insn-size.  There are hooks for this
in various places, but no one has finished the work.  It's straightforward,
more leg-work than brain-work.  I'll make a point of getting to it
this week (can't promise an ETA, but we shall see).

---

(*1): `df' should actually be the real full form, not an abbreviated form that
leaves out the ability to specify things necessary in ciscy ISAs.
`dfrf' [define-full-risc-field] or some-such would have been a better choice
for the current `df'.

(*2): Anyone want to come up with a usable macro who's name is "dunno"?
Now that would be funny. :-)

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Again: variable width instructions
  2003-02-10  0:56 Again: variable width instructions Doug Evans
@ 2003-02-11 13:42 ` Manuel Kessler
  0 siblings, 0 replies; 4+ messages in thread
From: Manuel Kessler @ 2003-02-11 13:42 UTC (permalink / raw)
  To: cgen

Thanks first to Doug and Jan for their helpful comments.

On Sun, 9 Feb 2003, Doug Evans wrote:

> Things might actually be working ok, depending upon whether or not
> $0x80000000, etc. are valid symbols.  What's happening is that
> gas is interpreting them as symbols ($ doesn't prefix constants in
> fr30 assembler).  If you had included -r in the arguments to objdump
> you would have seen the following.  Live and learn I guess. :-)

Feeling a little embarrassed, but who knows fr30 assembler anyway ;-)

> Regarding problems specifying ciscy fields in m16c.cpu, Jan is right.
> You (probably) want to use the full form of define-ifield for these.
> It's unfortunate that I didn't create a shorthand version of the
> full form of define-ifield, I think its absence has led to some confusion.
> E.g. You don't need #lsb0 = #f, it just makes the abbreviated short forms
> dnf and df [sic (*1)] work better.

Yes, I have been playing with lsb0=#t and #f, and I think there is some
problem with #t, possibly only in combination with little endian.
Attached you will find my updated m16c.cpu file, which nearly works with 
xxx-insn-bitsize 16. As I need constant fields in the second byte, I
probably cannot go down to 8 currently, but that's ok for me now.
For testing, I defined some ifields with the full form, especially take a
look at f-opc1b, which is an opcode part in the second byte. If I define
it with word-offset 8 and start 5, the opcode part (0x2f) does not end up
in the corresponding bits of the second byte, but gets added to the first
byte! However, if I define it with word-offset 0 and start 13, the
behaviour is correct?!? Interestingly enough, the nearly identical
definition of the register part in the second byte (which is obviously
not constant, but depends on the chosen register) is working both ways.

To make matters worse, in one combination of lsb0, word-offset and
xxx-bitsize (can't remember exactly, and am too lazy to reproduce, so
feel very free to ignore this paragraph), the assembled bytes were
correct, but objdump couldn't disassemble them back, so some information
was included in the assembler, but missing in the disassembler or vice
versa.

Anyway, there is a way to do it, so it's okay. The problem occurs if I go
to the variant including 8bit displacement, which is 24bit long
(negi8). If I leave the displacement field out (disp8), the two opcodes in
the first two bytes get assembled correctly, but naturally the
displacement is missing. If I include the displacement field in the
instruction definition, the displacement gets filled in the correct place
and the next instruction starts at the correct position 24bits later, but
the two opcode bytes get screwed up. More specifically, the opcode part
which belongs to bits 0-6 (lsb0=#t) of the second byte, vanishes
completely, as do bits 6-7 of the first byte, and bits 4-5 of the first
byte show up in their proper positions in the second byte.

So that's the current state of affairs. Feel free again to comment on the
attached m16c.cpu file.
 
> I went to savannah.nongnu.org and checked out and built an m16c toolchain
> (but using the m16c.cpu file you included in your message).

Thank you very much for getting this far!
 
> I can see some of the problems you're having.  For example,
> 
> 	neg.b 4[a0]
> 
> disassembles to
> 
>    0:	a2 2f 04 42 	*unknown*
> 
> but it's only a 3 byte insn.

It is clear that any unknown instruction gets disassebled as
base-insn-bitsize, but if it gets disassembled, then with the proper
length.

> You really do want to use the proper values of 8 for base-insn-size, etc.
> 
>   (default-insn-bitsize 8)
>   (base-insn-bitsize 8)
>   (default-insn-word-bitsize ???)
> 
> Off the top of my head I dunno what's a good value for
> default-insn-word-bitsize for the m16c.
> 
> Given that base-insn-bitsize is 8 you'll want to use the full form of
> define-ifield, or the macros that are in your m16.cpu file: dif and dnif (*2).
> 
> There's one more problem though.  Cgen current doesn't support ifields
> with constant values beyond base-insn-size.  There are hooks for this
> in various places, but no one has finished the work.  It's straightforward,
> more leg-work than brain-work.  I'll make a point of getting to it
> this week (can't promise an ETA, but we shall see).

Of course I do want the correct xxx-bitsize, but as I need the constant
ifields beyond 8 bits I (currently, at least) have little choice. 16 would
be fine, if I can make it work.

Thanks again for all the help up to now, but gratefuls as I am I will
still beg for more :-)

Ciao,
	Manuel

______________________________________________________________________
  
Dr. Manuel Kessler, Dipl.-Phys.

Institut fuer Aerodynamik und Gasdynamik
Universitaet Stuttgart
Pfaffenwaldring 21           ( ( ( ( ___________.^.___________ ) ) ) )
70550 Stuttgart / Germany                      _\I/_                
                                              /\_|_/\
Phone:      +49 711 685 3435                  \_(_)_/ 
Fax:        +49 711 685 3438                 ./     \.
E-Mail:     kessler@iag.uni-stuttgart.de               
WWW:        http://www.iag.uni-stuttgart.de/people/manuel.kessler
______________________________________________________________________

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Again: variable width instructions
  2003-02-07 14:40 ` Again: " Manuel Kessler
@ 2003-02-07 21:06   ` Jan Zizka
  0 siblings, 0 replies; 4+ messages in thread
From: Jan Zizka @ 2003-02-07 21:06 UTC (permalink / raw)
  To: cgen

Hi!

I had the same problem. I'm porting binutils to DSP56800. Normal instructions
have 16bits but eventually this may increase to 48 (3 words). I've solved it by
defininig the immediate instruction fields as:

(define-ifield  
  (name f-imm16)
  (comment "16b imm data")
  (attrs)
  (word-offset 16)
  (word-length 16)
  (start 15)
  (length 16)
  (mode UINT)
)

(define-ifield  
  (name f-imm16w3)
  (comment "16b imm data in third word")
  (attrs)
  (word-offset 32)
  (word-length 16)
  (start 15)
  (length 16)
  (mode UINT)
)

so when the word-offset is 0 it accesses first 16 bits (I have 16 bit insns
base), when it is 16 then the next word etc.
You can see the effect on following instructions:

(define-pmacro (move18 mnemonic opcode)
  (dni (.sym "move18-" mnemonic) 
	  (.str mnemonic " #imm16,X:imm16")
	  ()
	  (.str mnemonic " #$imm16w3,X:$imm16")
	  (+ (f-op-16 opcode) imm16 imm16w3)
	  ()
	  ()
  )
)

and example:

DSP56800 GAS  test16.asm                        page 1


   1                    test:
   2 0000 E040                            nop
   3 0001 8504                            move a,b
   4 0002 86F42000                        move #$1000,X:$2000
   4      1000
   5 0005 81C4FFFF                        bfclr #$FFFF,A
   6 0007 89DE0080                        bftstl #128,LC

DSP56800 GAS  test16.asm                        page 2


DEFINED SYMBOLS
          test16.asm:1      .text:00000000 test

NO UNDEFINED SYMBOLS

and obj dump:

a.out:     file format elf32-dsp56800

Disassembly of section .text:

00000000 <test>:
   0:   e0 40           nop
   1:   85 04           move A,B
   2:   86 f4 20 00     move #0xffff,X:0x1000
   4:   10 00 
   5:   81 c4 ff ff     bfclr #0xffff,A
   7:   89 de 00 80     bftstl #0x80,LC

So this should work also for you :), try it out! At least I hope that this is
the effect you want to obtain!?

Regards
              Jan

--- Manuel Kessler <mlkessle@cip.physik.uni-wuerzburg.de> wrote:
> Five or six weeks ago David Carney asked how to handle instructions with
> fields beyond the usual instruction size, which is rather CISC-ish. While
> Frank and Doug responded quickly, how to handle this situation, by
> defining just fields starting at the next bit (and the trick to define
> lsb0? to #f), he did not succeed. As he told me, he had to move on to
> other things, and so got distracted.
> 
> However, I am in a similar situation, trying to accomplish more or less
> the same thing. While for my microcontroller (Mitsubishi M16C, if anybody
> is interested) instructions may be as short as 8 bits, with operands,
> immediates and prefixes they may grow to up to 80 bits or so. I was able
> to assemble and disassemble the first instructions with different
> addressing modes (and correspondingly different lengths) by using
> xxx-insn-bitsize of 32 (instead of the 8 as suggested in the documentation
> for the smallest instruction), but for instructions even longer than that
> my attempts were not successful. While I can define instruction fields
> that late, I can not fill them with registers or immediates, this data
> (register indices etc.) gets stuck in the first portion of the
> instruction.
> 
> Doug mentioned the fr30 port as a guidline, which has a single instruction
> taking a 32 bit immediate and thus being longer than the others. However,
> this functionality seems to be gone. The same problem is there: The
> immediate data does not get filled in the appropriate slot. I took this
> file:
> 
> ; test file for ldi32
>         ldi:32 $0x80000000, r0
>         nop
>         ldi:32 $0x00000000, r1
>         nop
>         ldi:32 $0xffffffff, r2
>         nop
>         ldi:32 $0x7fffffff, r3
>         nop
> .end
> 
> assembled it, and objdump of the result told me:
> 
> a.out:     file format elf32-fr30
> 
> Disassembly of section .text:
> 
> 00000000 <.text>:
> in disassemble_bytes
>    0:   9f 80 00 00     ldi:32 0x0,r0
>    4:   00 00
>    6:   9f a0           nop
>    8:   9f 81 00 00     ldi:32 0x0,r1
>    c:   00 00
>    e:   9f a0           nop
>   10:   9f 82 00 00     ldi:32 0x0,r2
>   14:   00 00
>   16:   9f a0           nop
>   18:   9f 83 00 00     ldi:32 0x0,r3
>   1c:   00 00
>   1e:   9f a0           nop
> 
> As you can see, the immediate data vanishes somewhere in between.
> 
> I am kind of stuck now. Is there still a trick I have been missing, or are
> variable width instructions currently broken, or only fields beyond the
> first instruction portion? 
> I hope desperately there is a simple fix to this problem.
> 
> Thanks for your time.
> 
> Ciao,
> 	Manuel
> 
> PS: For the curious I have attached the current state of my m16c.cpu
> file (I am not sure if it will make it to the list). Feel free to comment
> on it, and find further information and a CVS repository of the will-be


__________________________________________________
Do you Yahoo!?
Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
http://mailplus.yahoo.com

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Again: variable width instructions
  2002-12-20 14:59 David Carney
@ 2003-02-07 14:40 ` Manuel Kessler
  2003-02-07 21:06   ` Jan Zizka
  0 siblings, 1 reply; 4+ messages in thread
From: Manuel Kessler @ 2003-02-07 14:40 UTC (permalink / raw)
  To: cgen

[-- Attachment #1: Type: TEXT/PLAIN, Size: 2767 bytes --]

Five or six weeks ago David Carney asked how to handle instructions with
fields beyond the usual instruction size, which is rather CISC-ish. While
Frank and Doug responded quickly, how to handle this situation, by
defining just fields starting at the next bit (and the trick to define
lsb0? to #f), he did not succeed. As he told me, he had to move on to
other things, and so got distracted.

However, I am in a similar situation, trying to accomplish more or less
the same thing. While for my microcontroller (Mitsubishi M16C, if anybody
is interested) instructions may be as short as 8 bits, with operands,
immediates and prefixes they may grow to up to 80 bits or so. I was able
to assemble and disassemble the first instructions with different
addressing modes (and correspondingly different lengths) by using
xxx-insn-bitsize of 32 (instead of the 8 as suggested in the documentation
for the smallest instruction), but for instructions even longer than that
my attempts were not successful. While I can define instruction fields
that late, I can not fill them with registers or immediates, this data
(register indices etc.) gets stuck in the first portion of the
instruction.

Doug mentioned the fr30 port as a guidline, which has a single instruction
taking a 32 bit immediate and thus being longer than the others. However,
this functionality seems to be gone. The same problem is there: The
immediate data does not get filled in the appropriate slot. I took this
file:

; test file for ldi32
        ldi:32 $0x80000000, r0
        nop
        ldi:32 $0x00000000, r1
        nop
        ldi:32 $0xffffffff, r2
        nop
        ldi:32 $0x7fffffff, r3
        nop
.end

assembled it, and objdump of the result told me:

a.out:     file format elf32-fr30

Disassembly of section .text:

00000000 <.text>:
in disassemble_bytes
   0:   9f 80 00 00     ldi:32 0x0,r0
   4:   00 00
   6:   9f a0           nop
   8:   9f 81 00 00     ldi:32 0x0,r1
   c:   00 00
   e:   9f a0           nop
  10:   9f 82 00 00     ldi:32 0x0,r2
  14:   00 00
  16:   9f a0           nop
  18:   9f 83 00 00     ldi:32 0x0,r3
  1c:   00 00
  1e:   9f a0           nop

As you can see, the immediate data vanishes somewhere in between.

I am kind of stuck now. Is there still a trick I have been missing, or are
variable width instructions currently broken, or only fields beyond the
first instruction portion? 
I hope desperately there is a simple fix to this problem.

Thanks for your time.

Ciao,
	Manuel

PS: For the curious I have attached the current state of my m16c.cpu
file (I am not sure if it will make it to the list). Feel free to comment
on it, and find further information and a CVS repository of the will-be
binutils port at
http://savannah.nongnu.org/projects/m16c/

[-- Attachment #2: Type: TEXT/PLAIN, Size: 11881 bytes --]

; Open questions:
; - why doesn't $size work in disassembly???
; - why do we have to use base-insn-bitsize=16/32 ?
; - address/index registers are currently WI, but should be AI
;   -> CGEN problem, even if HI -> semantic access to with mem doesn't work

; Mitsubishi M16C CPU description.  -*- Scheme -*-
; Copyright (C) 2002 Manuel Kessler

(include "simplify.inc")

; FIXME: Delete sign extension of accumulator results.
; Sign extension is done when accumulator is read.

; define-arch must appear first

(define-arch
  (name m16c) ; name of cpu family
  (comment "Mitsubishi M16C")
  (default-alignment aligned)
  (insn-lsb0? #t)
  (machs m16c8x)
  (machs m16c6x m16c8x m32c8x)
  (isas m16c)
)

; Instruction set parameters.
; FIXME: I think 8/8/8 would be more correct, but constant fields seem to be
; not allowed beyond base-insn-bitsize, and it seems to work (mostly) ok
; this way. Perhaps come back to this issue later.
(define-isa
  (name m16c)
  (default-insn-bitsize 32)
  (base-insn-bitsize 32)
  (default-insn-word-bitsize 32)
)

; Cpu family definitions.

(define-cpu
  ; cpu names must be distinct from the architecture name and machine names.
  ; The "b" suffix stands for "base" and is the convention.
  ; The "f" suffix stands for "family" and is the convention.
  (name m16cbf)
  (comment "Mitsubishi M16C6x base family")
  (endian little)
)

(define-cpu
  (name m32cf)
  (comment "Mitsubishi M16C8x/M32C8x family")
  (endian little)
  ; Generated files have an "x" suffix.
  (file-transform "x")
)

(define-mach
  (name m16c6x)
  (comment "Generic M16C6x cpu")
  (cpu m16cbf)
)

(define-mach
  (name m16c8x)
  (comment "Generic M16C8x cpu")
  (cpu m32cf)
)

(define-mach
  (name m32c8x)
  (comment "Generic M32C8x cpu")
  (cpu m32cf)
)

; Model descriptions.

(define-model
  (name m16c60) (comment "M16C/60") (attrs)
  (mach m16c6x)
  (pipeline all "" () ((fetch) (decode) (execute) (writeback)))
  (unit u-exec "Execution Unit" ()
	1 1 ; issue done
	() () () ())
)

(define-model
  (name m16c80) (comment "M16C/80") (attrs)
  (mach m16c8x)
  (pipeline all "" () ((fetch) (decode) (execute) (writeback)))
  (unit u-exec "Execution Unit" ()
	1 1 ; issue done
	() () () ())
)

(define-model
  (name m32c80) (comment "M32C/80") (attrs)
  (mach m32c8x)
  (pipeline all "" () ((fetch) (decode) (execute) (writeback)))
  (unit u-exec "Execution Unit" ()
	1 1 ; issue done
	() () () ())
)

; register file definitions
(define-keyword
  (name gr8-names)
  (print-name h-gr8)
  (prefix "")
  (values (r0h 0) (r1h 1) (r0l 2) (r1l 3))
)

(define-hardware
  (name h-gr8)
  (comment "8 bit general registers")
  (attrs VIRTUAL PROFILE)
  (type register QI (4))
  (indices extern-keyword gr8-names)
  (get (index)
       (if (gt index 1)
	   (reg QI h-gr index)
	   (bitfield (reg h-gr (add index 2)) 15 8)))
  (set (index newval)
       (if (gt index 1)
	   (set (bitfield (reg h-gr index) 8 8) newval)
	   (set (bitfield (reg h-gr (add index 2)) 15 8) newval)))
)

(define-keyword
  (name gr-names)
  (print-name h-gr)
  (prefix "")
  (values (r2 0) (r3 1) (r0 2) (r1 3))
)

(define-hardware
  (name h-gr)
  (comment "general registers")
  (attrs PROFILE CACHE-ADDR)
  (type register HI (4))
  (indices extern-keyword gr-names)
)

(define-keyword
  (name ar-names)
  (print-name h-ar)
  (prefix "")
  (values (a0 0) (a1 1))
)

(define-hardware
  (name h-ar)
  (comment "address registers")
  (attrs VIRTUAL PROFILE)
  (type register WI (2))
  (indices extern-keyword ar-names)
  (get (index) (reg h-ir index))
  (set (index newval) (set reg h-ir index newval))
)

(define-keyword
  (name br-names)
  (print-name h-br)
  (prefix "")
  (values (sb 0) (fb 1))
)

(define-hardware
  (name h-br)
  (comment "address registers")
  (attrs VIRTUAL PROFILE)
  (type register WI (2))
  (indices extern-keyword br-names)
  (get (index) (reg h-ir (add index 2)))
  (set (index newval) (set reg h-ir (add index 2) newval))
)

(define-keyword
  (name ir-names)
  (print-name h-ir)
  (prefix "")
  (values (a0 0) (a1 1) (sb 2) (fb 3))
)

(define-hardware
  (name h-ir)
  (comment "index registers")
  (attrs PROFILE CACHE-ADDR)
  (type register WI (4))
  (indices extern-keyword ir-names)
)

(define-keyword
  (name gr32-names)
  (print-name h-gr32)
  (prefix "")
  (values (r2r0 0) (r3r1 1))
)

(define-hardware
  (name h-gr32)
  (comment "32 bit combined general registers")
  (attrs VIRTUAL PROFILE)
  (type register WI (16))
  (indices extern-keyword gr32-names)
  (get (index) (add (reg HI h-gr (add (mul index 2) 1))
  					(sll (reg HI h-gr (mul index 2)) 16)))
  (set (index newval) (parallel ; FIXME do both halves??
  		(set (subword HI h-gr (reg h-gr index) 15 16) newval)))
)

(define-keyword
  (name cr8-names)
  (print-name h-cr8)
  (prefix "")
  (values (dct0 0) (dct1 1) (flg 2) (svf 3)
	(drc0 4) (drc1 5) (dmd0 6) (dmd1 7))
)

(define-hardware
  (name h-cr8)
  (comment "8 bit control registers")
  (attrs PROFILE CACHE-ADDR)
  (type register QI (8))
  (indices extern-keyword cr8-names)
)

(define-keyword
  (name cr24a-names)
  (print-name h-cr24a)
  (prefix "")
  (values (intb 0) (sp 1) (sb 2) (fb 3) (svp 4) (vct 5) (isp 7))
)

(define-hardware
  (name h-cr24a)
  (comment "24 bit control registers")
  (attrs PROFILE CACHE-ADDR)
  (type register WI (8))
  (indices extern-keyword cr24a-names)
)

(define-keyword
  (name cr24b-names)
  (print-name h-cr24b)
  (prefix "")
  (values (dma0 2) (dma1 3) (dra0 4) (dra1 5) (dsa0 6) (dsa1 7))
)

(define-hardware
  (name h-cr24b)
  (comment "24 bit control registers")
  (attrs PROFILE CACHE-ADDR)
  (type register WI (8))
  (indices extern-keyword cr24b-names)
)

(define-hardware
  (name h-size)
  (comment "size suffix")
  (type immediate (UINT 1))
  (values keyword "." ((b 0) (w 1) ))
)

; For condbit operand.  FIXME: Need to allow spec of get/set of operands.
; Having this separate from h-psw keeps the parts that use it simpler
; [since they greatly outnumber those that use h-psw].

(dsh h-cond "condition bit" () (register BI))

(dnh h-pc "program counter" (PC PROFILE) (pc) () () ())

; operand fields
; copied from ia32.cpu
; There currently doesn't exist shorthand macros for CISC ISA's,
; so define our own.
; DIF: define-ia32-field
; DNIF: define-normal-ia32-field

(define-pmacro (dif x-name x-comment x-attrs x-word-offset x-word-length x-start x-length x-mode x-encode x-decode)
  (define-ifield
    (name x-name)
    (comment x-comment)
    (.splice attrs (.unsplice x-attrs))
    (word-offset x-word-offset)
    (word-length x-word-length)
    (start x-start)
    (length x-length)
    (mode x-mode)
    (encode x-encode)
    (decode x-decode)
    )
)

(define-pmacro (dnif x-name x-comment x-attrs x-word-offset x-word-length x-start x-length)
  (dif x-name x-comment x-attrs x-word-offset x-word-length x-start x-length
       UINT #f #f)
)

; operand 1 mode select
(dnf f-op1m      "op1m"     () 3 1)
; operand 1 displacement size select
(dnf f-op1i      "op1i"     () 2 2)
; operand 1 register select
(dnf f-op1r      "op1r"     () 15 2)
; operand 1 address mode select
(dnf f-op1am     "op1am"    () 15 1)
; operand 1 address register select
(dnf f-op1ar     "op1ar"    () 14 1)

; dito for operand 2
(dnf f-op2m      "op2m"     () 6 1)
(dnf f-op2i      "op2i"     () 5 2)
(dnf f-op2r      "op2r"     () 13 2)
;(dnmf f-op2      "op2"      () UINT (f-op2m f-op2i f-op2r) #f #f)

; operand size select
(dnf f-size      "size"     () 0 1)

; condition select
(dnf f-cond      "cond"     () 12 4)


(df f-disp8      "disp8"    () 23 8 INT #f #f)
(df f-disp16     "disp16"   () 31 16 INT #f #f)
(df f-disp24     "disp24"   () 39 24 INT #f #f)
(dnop disp8      "disp8"    () h-iaddr f-disp8)
(dnop disp16     "disp16"   () h-iaddr f-disp16)
(dnop disp24     "disp24"   () h-iaddr f-disp24)

; Instruction fields.

(define-pmacro (build-hex1 num) (.hex num 1))
(define-pmacro (build-hex2 num) (.hex num 2))

(dnf f-opcode "single insn byte"         () 7 8)
(dnf f-opc1   "opcode single operand"    () 7 4)
(dnf f-opc1b  "opcode single operand #2" () 13 6)
(dnf f-opc1m  "opcode mode"              () 3 3)
(dnf f-opcs   "opcode size"              () 0 1)


; insn-opcode
; "00" ... "FF"
;(define-normal-insn-enum insn-opcode "insn opcode enums" () OP_ f-opcode
;  (.map .upcase (.map build-hex2 (.iota 256)))
;)

; insn-op1: bits 7-4
;(define-normal-insn-enum insn-op1 "insn opcode enums (1 op)" () OP1_ f-opc1
;  (.map .upcase (.map build-hex1 (.iota 16)))
;)
; insn-op1: bits 13-8
;(define-normal-insn-enum insn-op1b "insn opcode enums (1 op, #2)" () OP1B_ f-opc1b
;  (.map .upcase (.map build-hex2 (.iota 64)))
;)
; insn-op1m: bits 3-1
(define-normal-insn-enum insn-op1m "insn opcode modes (1 op)" () OP1M_ f-opc1m
	("A" "8A" "16A" "24A" "R")
)
; insn-op1s: bit 0
(define-normal-insn-enum insn-op1s "insn opcode size" () OPS_ f-opcs
	("B" "W")
)
; insn-op1am: bit 15
(define-normal-insn-enum insn-op1am "insn opcode address mode (1 op)" () OP1AM_ f-op1am
	("I" "D") ; direct/indirect a0/a1 respectively [a0]/[a1]
)

(define-attr
  (for operand)
  (type boolean)
  (name HASH-PREFIX)
  (comment "immediates have an optional '#' prefix")
)

(dnop sr     "source register"              () h-gr   f-op2r)
(dnop dr     "destination register"         () h-gr   f-op1r)
(dnop sr8    "source register"              () h-gr8  f-op2r)
(dnop dr8    "destination register"         () h-gr8  f-op1r)
(dnop ir     "index register"               () h-ir   f-op1r)
(dnop ar     "address register"             () h-ar   f-op1ar)

(dnop size   "size suffix"                  () h-size f-opcs)

;(dnop si     "source indirect"              () h-gr   f-op2r)
;(dnop di     "destination indirect"         () h-gr   f-op1r)

; Instructions

(dni nop "nop"
     ()
     "nop"
     (+ (f-opcode #xDE))
     (nop)
     ()
)

;NEG.size 1010dddS dd101111
; ddd=100 for r8/r16
(dni neg "neg"
     ()
     "neg.w $dr"
     (+ (f-opc1 #xA) OP1M_R OPS_W (f-opc1b #x2f) dr)
     (set dr (neg dr))
     ()
)
(dnmi neg- "neg alias"
     (NO-DIS)
     "neg $dr"
     (emit neg dr)
)

(dni neg8 "neg8"
     ()
     "neg.b $dr8"
     (+ (f-opc1 #xA) OP1M_R OPS_B (f-opc1b #x2f) dr8)
     (set dr8 (neg dr8))
     ()
)
(dnmi neg8- "neg8 alias"
     (NO-DIS)
     "neg $dr8"
     (emit neg8 dr8)
)

(dni nega "nega"
     ()
     "neg.w $ar"
     (+ (f-opc1 #xA) OP1M_A OPS_W (f-opc1b #x2F) OP1AM_D ar)
     (set ar (and (neg ar) 65535))
     ()
)
(dnmi nega- "nega alias"
     (NO-DIS)
     "neg $ar"
     (emit nega ar)
)

; ddd=0001 for a0/a1
(dni negaiw "negaiw"
     ()
     "neg$size [$ar]"
     (+ (f-opc1 #xA) OP1M_A size (f-opc1b #x2F) OP1AM_I ar)
     (if size
     	(set (mem HI ar) (neg (mem HI ar)))
     	(set (mem QI ar) (neg (mem QI ar)))
     )
     ()
)

(dni negi8 "negi8"
     (RELAXABLE)
     "neg$size $disp8[$ir]"
     (+ (f-opc1 #xA) OP1M_8A size (f-opc1b #x2F) ir disp8)
     (if size
     	(set (mem HI (add ir disp8)) (neg (mem HI (add ir disp8))))
     	(set (mem QI (add ir disp8)) (neg (mem QI (add ir disp8))))
     )
     ()
)
;(dnmi negb- "neg.X 0[$br] alias"
;     (NO-DIS)
;     "neg$size [$br]"
;     (expand neg$1 0[$2])
;)


(dni negi16 "negi16"
     ()
     "neg$size $disp16[$ir]"
     (+ (f-opc1 #xA) OP1M_16A size (f-opc1b #x2F) ir disp16)
     (if size
     	(set (mem HI (add ir disp16)) (neg (mem HI (add ir disp16))))
     	(set (mem QI (add ir disp16)) (neg (mem QI (add ir disp16))))
     )
     ()
)







^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2003-02-11 13:42 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-02-10  0:56 Again: variable width instructions Doug Evans
2003-02-11 13:42 ` Manuel Kessler
  -- strict thread matches above, loose matches on Subject: below --
2002-12-20 14:59 David Carney
2003-02-07 14:40 ` Again: " Manuel Kessler
2003-02-07 21:06   ` Jan Zizka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).