1 Instruction Set Architecture
| (require ledum/define/isa) | package: ledum-definers |
This module allows for defining custom ISA. It provides syntax forms for extending the ISA and facilities for encoding, decoding and evaluating the ISA in both source and binary forms.
Reexports isa0 struct from ledum/define/isa/struct0.
syntax
maybe-option =
| #:bits bits maybe-option | #:signeds (sl ...) maybe-option | #:doc (doc ...) maybe-option sl = letter
isa : identifier?
bits : exact-exact-positive-integer?
The list of #:signeds is used to determine which opcode bitmask letters represent signed immediate value.
syntax
(define-isa-opcode maybe-private (name args maybe-order) maybe-doc body ...)
maybe-private =
| #:private name = identifier? args = bits-wide bitmask maybe-order =
| #:order arg ... maybe-doc =
| #:doc (doc ...) Defines a new opcode for given ISA using define-opcode.Adds the new opcode to given isa.
The body ... expressions should be the behavioral description used for emulation.
syntax class
isa-word
A bits-bits integer which can be used in macro instruction specification patterns.
syntax
(define-isa-entity ex ...)
syntax
(define-isa-next ex ...)
Specifies a procedure for fetching the next instruction on this ISA.
1.1 ISA Structs
| (require ledum/define/isa/struct0) | package: ledum-definers |
This module contains the structs required by ISA specification which do not pull in unnecessary dependencies.
procedure
(add-isa-opcode! isa opc) → void?
isa : isa0? opc : opcode?
struct
id : symbol? bits : (listof exact-nonnegative-integer?)
procedure
oa : opcarg?
struct
name : symbol? mask : exact-nonnegative-integer? value : nonegative-integer? eval : (-> exact-nonnegative-integer? void?) enc : procedure? args : (listof opcarg?) bitw : exact-positive-integer? dec : (-> exact-nonnegative-integer? list?)
struct
ids : (listof symbol?) chars : (listof symbol?) nums : (listof exact-nonnegative-integer?) ctr : (-> any/c boolean?)
procedure
e : ent0?
1.1.1 Phase 1 ISA Structs
| (require ledum/define/isa/struct1) | package: ledum-definers |
These structures are used during expansion.
struct
(struct isa1 (trans entmap signs))
trans : procedure? entmap : hash? signs : (listof symbol?)
The entmap entities map contains mapping of letters to particular syntax class. And the signs list contains all the letter symbols used in opcode masks as signed immediates.
struct
(struct ent1 (num cls))
num : exact-nonnegative-integer? cls : symbol?
1.2 ISA Opcode
| (require ledum/define/isa/opcode) | package: ledum-definers |
syntax
(define-opcode maybe-private isa #:bitw bitw (name args maybe-order) maybe-doc body ...)
maybe-private =
| #:private args = bit-width-wide bitmask maybe-order =
| #:order arg ... maybe-doc =
| #:doc (doc ...)
name : identifier?
Defines a new opcode.
Opcodes defined as #:private can only be used in macro opcode specification - see define-macro-opcode for more information.
The bitmask is an identifier? starting with the : character and having exactly bit-width significant characters. Significant characters are the digits 0 and 1 and any lower-case or upper-case ASCII characters a-z.
In addition to significant characters, spacing characters _ and - can be used to logically group the bits into clearer structure.
The digits specify the opcode mask and value.
The letters specify arguments of the opcode. All bits of the same letter are interpreted as n-bit value with all the bits put together in the same order but without gaps. A binding for each individual letter is created which can be used in the opcode body as normal procedure argument.
Inside the body expressions allow-private-opcodes and allow-raw-entities are enabled.
When the order of the arguments in assembler syntax is to be different than the order of appearance of given argument in the mask, an explicit ordering can be specified with the #:order keyword. In such case all the arguments positions must be explicitly specified.
A default documentation for the assembler syntax form is generated. Any prose text can be added to it with the #:doc keyword. This is especially useful coupled with the at-exp meta-language.
Take the following example code:
(define-isa-opcode (ldl :0001-rrrr-iiii-iiii) #:doc @{Load an 8-bit constant @racket[i] into the register @racket[r], clearing its higher 8 bits.} (displayln `(ldl ,r ,i))) It produces the documentation as follows:
opcode
(ldl r i)
r : (integer-in 0 15)
i : (integer-in 0 255) Load an 8-bit constant i into the register r, clearing its higher 8 bits.
1.3 Entities Encoding
| (require ledum/define/isa/entity) | package: ledum-definers |
This module adds support for encoded entities like registers or flag groups.
syntax
cls = identifier? eid = identifier? l = letter maybe-doc =
| #:doc (doc ...)
isa : isa0?
The letters l ... are injected into the isa and associated with the generated syntax class.
1.4 ISA Decoder Tree
| (require ledum/define/isa/optree) | package: ledum-definers |
Binary tree for efficient decoding of given ISA. Used both by the disassembler and emulator.
struct
(struct optn (bit left right))
bit : exact-nonnegative-integer? left : (or/c #f optn? optl? opterr?) right : (or/c #f optn? optl? opterr?)
struct
(struct optl (opcode unused bitw))
opcode : opcode? unused : exact-nonnegative-integer? bitw : exact-positive-integer?
struct
(struct optree (root bitw))
root : (or/c optn? optl? opterr?) bitw : exact-positive-integer?
procedure
(build-optree opl) → optree?
opl : (listof opcode?)
procedure
(print-optree opt) → void?
opt : optree?
procedure
(match-optree-opcode opt num) → opcode?
opt : optree? num : exact-nonnegative-integer?
struct
(struct optu (mask value umask bitw))
mask : exact-nonnegative-integer? value : exact-nonnegative-integer? umask : exact-nonnegative-integer? bitw : exact-positive-integer?
procedure
ou : optu?
procedure
(analyze-optree opt) → (listof optu?)
opt : optree?
Returns a list of unused bit masks which were not used to recognize any particular opcode in the current opcode tree of given is. The actual number of unused bits cannot be directly used for determining the number of unused opcodes as one of those bits must be used to distinguish some existing opcode tree leaf. Therefore the number of free opcodes is always 2^{n-1} where n is the number of unused bits reported by this procedure.
procedure
(analyze-optree-depth opt)
→ (listof exact-nonnegative-integer?) opt : optree?
1.5 ISA Syntaxes
| (require ledum/define/isa/syntax) | package: ledum-definers |
This module contains the syntax abstractions common to other modules.
syntax
id = identifier? maybe-desc =
| #:description description-string
n : exact-positive-integer?
1.6 ISA Utilities
| (require ledum/define/isa/util) | package: ledum-definers |
Various ISA utilities, mostly re-exported by ledum/define/isa.
procedure
(isa-evaluator is) → (-> exact-nonnegative-integer? any)
is : isa0?
procedure
(isa-disassembler is) → (-> exact-nonnegative-integer? list?)
is : isa0?
procedure
(isa-analyze-depth) → void?
1.7 Opcode Emitter
| (require ledum/define/isa/emitter) | package: ledum-definers |
A separate module with only the emitter parameter so that it can be required by assembler without pulling in further dependencies.
parameter
(opcode-emitter) → procedure?
(opcode-emitter proc) → void? proc : procedure?
The default emitter just prints the opcode as hexadecimal number to (current-output-port).
1.8 Opcode Visualizer
| (require ledum/define/isa/ompict) | package: ledum-definers |
This module is used internally to include visual representations of opcode masks in the documentation. Although it is not intended to be used directly, it can be parameterized to make subtle changes to the generated pictures.
parameter
(ompict-colors) → (or/c #f 'ibm 'wong 'tol)
(ompict-colors scheme) → void? scheme : (or/c #f 'ibm 'wong 'tol)