lightning
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Lightning] Runtime assembler in C++


From: Pippijn van Steenhoven
Subject: [Lightning] Runtime assembler in C++
Date: Thu, 5 Jun 2008 15:52:58 +0200
User-agent: Mutt/1.5.18 (2008-05-17)

Hi Lightning List,

I am currently working on a C++ front-end for GNU Lightning. What I have
right now is a working parser for things like this:

  # mnemonic      op1             op2             op3     ret
  prolog          1
  arg_ui                                                  => $in
  getarg_ui       %v0             $in
  blti_ui         !forward        %v0             2       => @ref
  subi_ui         %v1             %v0             1
  subi_ui         %v2             %v0             2
  prepare_i       1
  pusharg_ui      %v1
  finish          @self         # The self-pointer is a pointer to the
                                # beginning of the code block (entry
                                # point). cf. fib.c
  retval_i        %v1
  prepare_i       1
  pusharg_ui      %v2
  finish          @self
  retval_i        %v2
  addi_ui         %v1             %v1             1
  addr_ui         %ret            %v1             %v2
  ret
  
  patch           @ref
  movi_i          %ret            1
  ret
  
This is the "fib" example. It has a limited form of type checking.
basically just whether you are passing imm, reg or insn. I do not yet
have differently sized types. Everything that is an immediate is passed
as int32_t. This might cause breakage on 64 bit platforms but I don't
know how to do the differently sized types, yet. I do not use the macros
directly, anymore. Instead, for each mnemonic, I use a C++ function. This
has produced many error messages. I fixed some, but I don't know whether
the fixes are correct. As far as I can remember (unfortunately I didn't
document my changes, so I'll probably redo them with documentation), I
added an _s32P macro which was used but missing and the LEAQmr
instruction for x86_64 which looks like this:

  #define LEAQmr(MD, MB, MI, MS, RD)      (_REXQmr(MB, MI, RD),           
_OO_r_X         (0x8d                ,_r8(RD)           ,MD,MB,MI,MS            
))

I am pretty new to machine code and therefore, I am not sure whether this
code is correct. There is a long list of instructions that do not work on
x86_64 because they do not exist or some other macro is being used
incorrectly. I am aware that x86_64 support is new, but even on i386-32,
many instructions do not exist. If you are interested, I can generate
this list.

The current assembler supports the following checks:

- Type checking (imm, reg, insn)
- Argument count check
- Return value check (it has to be used, even if you discard it)

It can also store the parsed lightning-asm code in a platform independent
(big endian) bytecode format. The parser does not check whether the
instruction exists. It just assumes it does. Only when the code is
actually assembled into machine code or stored to bytecode, these checks
are performed. The bytecode is very simple. Each instruction consists of
a 4-byte header, 0, 1, 2 or 3 argument blocks and an optional return
value block. The header looks like this:

  Bytes         Content
  1             Whether or not the instruction returns a value
  1             Argument count (0, 1, 2 or 3)
  2             Opcode

Each argument block starts with a 1-byte type-code which may be one of
var, label, call, reg_r, reg_v, reg_fp, reg_ret, imm. After that, it
depends on whether the operand is a string or an integer. String operands
are currently only var, label and call. Strings are stored with a 2-byte
length indicator and then the string content. Integers are stored as
4-byte blocks. The optional return block is just a string with its 2-byte
length. It refers to the variable or label name in which the return value
is stored. That's all.

By the way, is there any reason to have more than one "variable"?
Variables are integers returned by an instruction. Currently, the only
instructions that do this in my assembler are the lightning arg_*
instructions. I use a map<string, imm32> for them but I might as well
just store the value and give it a fixed name.

This is a lot of fun and I welcome any comments.

Regards,
  
-- 
Pippijn van Steenhoven

Attachment: signature.asc
Description: Digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]