|
View:
New views
5 Messages
—
Rating Filter:
Alert me
|
|
|
Runtime assembler in C++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 _______________________________________________ Lightning mailing list Lightning@... http://lists.gnu.org/mailman/listinfo/lightning |
|
|
Re: Runtime assembler in C++Pippijn van Steenhoven wrote:
> 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 )) These two I will look at. > 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. Yes, thanks! This can indeed be helpful, if only to stress test the back-ends. > 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. Yes, I don't remember other instructions that return arbitrary integers. I don't understand your question exactly, but: 1) there can be >1 argument to a function; 2) you could use fixed names like $1, $2, $3 -- but then, checking that these fixed names were actually defined is almost as complicated as keeping the map<>. Paolo _______________________________________________ Lightning mailing list Lightning@... http://lists.gnu.org/mailman/listinfo/lightning |
|
|
Re: Runtime assembler in C++Here are the error logs from each backend. Note that jit_state::pointer
is the union. By the way, what is the reason for the many function pointer types in the jit_code union? Isn't one function pointer and one data pointer type sufficient? After all, you still have to cast. -- Pippijn van Steenhoven == Branch == bltr_f ‘jit_bltr_f’ was not declared in this scope bler_f ‘jit_bler_f’ was not declared in this scope bgtr_f ‘jit_bgtr_f’ was not declared in this scope bger_f ‘jit_bger_f’ was not declared in this scope beqr_f ‘jit_beqr_f’ was not declared in this scope bner_f ‘jit_bner_f’ was not declared in this scope bunltr_f ‘jit_bunltr_f’ was not declared in this scope bunler_f ‘jit_bunler_f’ was not declared in this scope bungtr_f ‘jit_bungtr_f’ was not declared in this scope bunger_f ‘jit_bunger_f’ was not declared in this scope buneqr_f ‘jit_buneqr_f’ was not declared in this scope bltgtr_f ‘jit_bltgtr_f’ was not declared in this scope bordr_f ‘jit_bordr_f’ was not declared in this scope bunordr_f ‘jit_bunordr_f’ was not declared in this scope == Compare == ltr_f ‘jit_ltr_f’ was not declared in this scope ler_f ‘jit_ler_f’ was not declared in this scope gtr_f ‘jit_gtr_f’ was not declared in this scope ger_f ‘jit_ger_f’ was not declared in this scope eqr_f ‘jit_eqr_f’ was not declared in this scope ner_f ‘jit_ner_f’ was not declared in this scope unltr_f ‘jit_unltr_f’ was not declared in this scope unler_f ‘jit_unler_f’ was not declared in this scope ungtr_f ‘jit_ungtr_f’ was not declared in this scope unger_f ‘jit_unger_f’ was not declared in this scope uneqr_f ‘jit_uneqr_f’ was not declared in this scope ltgtr_f ‘jit_ltgtr_f’ was not declared in this scope ordr_f ‘jit_ordr_f’ was not declared in this scope unordr_f ‘jit_unordr_f’ was not declared in this scope == Function == prolog ‘_jit_prolog’ was not declared in this scope leaf ‘_jit_prolog’ was not declared in this scope == Jump == ret ‘_jit_epilog’ was not declared in this scope == Transfer == extr_f_d ‘jit_extr_f_d’ was not declared in this scope extr_d_f ‘jit_extr_d_f’ was not declared in this scope extr_i_f ‘jit_extr_i_f’ was not declared in this scope extr_i_d ‘jit_extr_i_d’ was not declared in this scope roundr_f_i ‘jit_roundr_f_i’ was not declared in this scope roundr_f_l ‘jit_roundr_f_l’ was not declared in this scope roundr_d_l ‘jit_roundr_d_l’ was not declared in this scope truncr_f_i ‘jit_truncr_f_i’ was not declared in this scope truncr_f_l ‘jit_truncr_f_l’ was not declared in this scope truncr_d_l ‘jit_truncr_d_l’ was not declared in this scope floorr_f_i ‘jit_floorr_f_i’ was not declared in this scope floorr_f_l ‘jit_floorr_f_l’ was not declared in this scope floorr_d_l ‘jit_floorr_d_l’ was not declared in this scope ceilr_f_i ‘jit_ceilr_f_i’ was not declared in this scope ceilr_f_l ‘jit_ceilr_f_l’ was not declared in this scope ceilr_d_l ‘jit_ceilr_d_l’ was not declared in this scope == Unary == negr_f ‘jit_negr_f’ was not declared in this scope notr_c ‘jit_xori_c’ was not declared in this scope notr_uc ‘jit_xori_c’ was not declared in this scope notr_s ‘jit_xori_s’ was not declared in this scope notr_us ‘jit_xori_s’ was not declared in this scope == Branch == bltr_f ‘jit_bltr_f’ was not declared in this scope bltr_d ‘jit_bltr_d’ was not declared in this scope bler_f ‘jit_bler_f’ was not declared in this scope bler_d ‘jit_bler_d’ was not declared in this scope bgtr_f ‘jit_bgtr_f’ was not declared in this scope bgtr_d ‘jit_bgtr_d’ was not declared in this scope bger_f ‘jit_bger_f’ was not declared in this scope bger_d ‘jit_bger_d’ was not declared in this scope beqr_f ‘jit_beqr_f’ was not declared in this scope beqr_d ‘jit_beqr_d’ was not declared in this scope bner_f ‘jit_bner_f’ was not declared in this scope bner_d ‘jit_bner_d’ was not declared in this scope bunltr_f ‘jit_bunltr_f’ was not declared in this scope bunltr_d ‘jit_bunltr_d’ was not declared in this scope bunler_f ‘jit_bunler_f’ was not declared in this scope bunler_d ‘jit_bunler_d’ was not declared in this scope bungtr_f ‘jit_bungtr_f’ was not declared in this scope bungtr_d ‘jit_bungtr_d’ was not declared in this scope bunger_f ‘jit_bunger_f’ was not declared in this scope bunger_d ‘jit_bunger_d’ was not declared in this scope buneqr_f ‘jit_buneqr_f’ was not declared in this scope buneqr_d ‘jit_buneqr_d’ was not declared in this scope bltgtr_f ‘jit_bltgtr_f’ was not declared in this scope bltgtr_d ‘jit_bltgtr_d’ was not declared in this scope bordr_f ‘jit_bordr_f’ was not declared in this scope bordr_d ‘jit_bordr_d’ was not declared in this scope bunordr_f ‘jit_bunordr_f’ was not declared in this scope bunordr_d ‘jit_bunordr_d’ was not declared in this scope == Transfer == roundr_f_l ‘jit_roundr_f_l’ was not declared in this scope roundr_d_l ‘jit_roundr_d_l’ was not declared in this scope truncr_f_l ‘jit_truncr_f_l’ was not declared in this scope truncr_d_l ‘jit_truncr_d_l’ was not declared in this scope floorr_f_l ‘jit_floorr_f_l’ was not declared in this scope floorr_d_l ‘jit_floorr_d_l’ was not declared in this scope ceilr_f_l ‘jit_ceilr_f_l’ was not declared in this scope ceilr_d_l ‘jit_ceilr_d_l’ was not declared in this scope == Unary == notr_c ‘jit_xori_c’ was not declared in this scope notr_uc ‘jit_xori_c’ was not declared in this scope notr_s ‘jit_xori_s’ was not declared in this scope notr_us ‘jit_xori_s’ was not declared in this scope == Binary operations == addxr_ul ‘jit_addxr_l’ was not declared in this scope addxr_l ‘jit_addxr_l’ was not declared in this scope addxi_ul ‘jit_addxi_l’ was not declared in this scope addxi_l ‘jit_addxi_l’ was not declared in this scope addcr_ul ‘jit_addcr_l’ was not declared in this scope addcr_l ‘jit_addcr_l’ was not declared in this scope addci_ul ‘jit_addci_l’ was not declared in this scope addci_l ‘jit_addci_l’ was not declared in this scope subxr_l ‘jit_subxr_l’ was not declared in this scope subxi_ul ‘jit_subxi_l’ was not declared in this scope subxi_l ‘jit_subxi_l’ was not declared in this scope subcr_ul ‘jit_subcr_l’ was not declared in this scope subcr_l ‘jit_subcr_l’ was not declared in this scope subci_ul ‘jit_addci_l’ was not declared in this scope subci_l ‘jit_addci_l’ was not declared in this scope mulr_l ‘jit_mulr_l’ was not declared in this scope mulr_ul ‘jit_mulr_ul’ was not declared in this scope muli_l ‘jit_muli_l’ was not declared in this scope muli_ul ‘jit_muli_ul’ was not declared in this scope hmulr_l ‘jit_hmulr_l’ was not declared in this scope hmulr_ul ‘jit_hmulr_ul’ was not declared in this scope hmuli_l ‘jit_hmuli_l’ was not declared in this scope hmuli_ul ‘jit_hmuli_ul’ was not declared in this scope divr_l ‘jit_divr_l’ was not declared in this scope divr_ul ‘jit_divr_ul’ was not declared in this scope divi_l ‘jit_divi_l’ was not declared in this scope divi_ul ‘jit_divi_ul’ was not declared in this scope modr_l ‘jit_modr_l’ was not declared in this scope modr_ul ‘jit_modr_ul’ was not declared in this scope modi_l ‘jit_modi_l’ was not declared in this scope modi_ul jit_modi_ul’ was not declared in this scope ori_l macro "jit_qop_" requires 5 arguments, but only 4 given ori_ul macro "jit_qop_" requires 5 arguments, but only 4 given xori_l macro "jit_qop_" requires 5 arguments, but only 4 given xori_ul macro "jit_qop_" requires 5 arguments, but only 4 given lshr_l macro "jit_qop_" requires 5 arguments, but only 3 given lshr_ul macro "jit_qop_" requires 5 arguments, but only 3 given rshr_l macro "jit_qop_" requires 5 arguments, but only 3 given rshr_ul macro "jit_qop_" requires 5 arguments, but only 3 given == Comparison == ltr_l ‘jit_ltr_l’ was not declared in this scope ltr_ul ‘jit_ltr_ul’ was not declared in this scope ltr_p ‘jit_ltr_ul’ was not declared in this scope lti_l ‘jit_lti_l’ was not declared in this scope lti_ul ‘jit_lti_ul’ was not declared in this scope lti_p ‘jit_lti_ul’ was not declared in this scope ler_l ‘jit_ler_l’ was not declared in this scope ler_ul ‘jit_ler_ul’ was not declared in this scope ler_p ‘jit_ler_ul’ was not declared in this scope lei_l ‘jit_lei_l’ was not declared in this scope lei_ul ‘jit_lei_ul’ was not declared in this scope lei_p ‘jit_lei_ul’ was not declared in this scope gtr_l ‘jit_gtr_l’ was not declared in this scope gtr_ul ‘jit_gtr_ul’ was not declared in this scope gtr_p ‘jit_gtr_ul’ was not declared in this scope gti_l ‘jit_gti_l’ was not declared in this scope gti_ul ‘jit_gti_ul’ was not declared in this scope gti_p ‘jit_gti_ul’ was not declared in this scope ger_l ‘jit_ger_l’ was not declared in this scope ger_ul ‘jit_ger_ul’ was not declared in this scope ger_p ‘jit_ger_ul’ was not declared in this scope gei_l ‘jit_gei_l’ was not declared in this scope gei_ul ‘jit_gei_ul’ was not declared in this scope gei_p ‘jit_gei_ul’ was not declared in this scope eqr_l ‘jit_eqr_l’ was not declared in this scope eqr_ul ‘jit_eqr_l’ was not declared in this scope eqr_p ‘jit_eqr_l’ was not declared in this scope eqi_l ‘jit_eqi_l’ was not declared in this scope eqi_ul ‘jit_eqi_l’ was not declared in this scope eqi_p ‘jit_eqi_l’ was not declared in this scope ner_l ‘jit_ner_l’ was not declared in this scope ner_ul ‘jit_ner_l’ was not declared in this scope ner_p ‘jit_ner_l’ was not declared in this scope nei_l ‘jit_nei_l’ was not declared in this scope nei_ul ‘jit_nei_l’ was not declared in this scope nei_p ‘jit_nei_l’ was not declared in this scope == Load == ldr_ui ‘jit_ldr_ui’ was not declared in this scope ldr_ul ‘jit_ldr_ul’ was not declared in this scope ldi_ui ‘jit_ldi_ui’ was not declared in this scope ldi_ul ‘jit_ldi_ul’ was not declared in this scope ldxr_ui ‘jit_ldxr_ui’ was not declared in this scope ldxr_ul ‘jit_ldxr_ul’ was not declared in this scope ldxi_ui ‘jit_ldxi_ui’ was not declared in this scope ldxi_ul ‘jit_ldxi_ul’ was not declared in this scope == Transfer == extr_c_l warning: left shift count >= width of type extr_s_l warning: left shift count >= width of type extr_i_l warning: left shift count >= width of type extr_f_d ‘jit_extr_f_d’ was not declared in this scope extr_d_f ‘jit_extr_d_f’ was not declared in this scope == Unary == negr_f ‘jit_negr_f’ was not declared in this scope negr_d ‘jit_negr_d’ was not declared in this scope notr_c ‘jit_xori_c’ was not declared in this scope notr_uc ‘jit_xori_c’ was not declared in this scope notr_s ‘jit_xori_s’ was not declared in this scope notr_us ‘jit_xori_s’ was not declared in this scope notr_l macro "jit_qop_" requires 5 arguments, but only 4 given notr_ul macro "jit_qop_" requires 5 arguments, but only 4 given == Branch == bltr_f ‘jit_bltr_f’ was not declared in this scope bltr_d macro "JZm" passed 4 arguments, but takes just 1 ‘union jit_state::pointer’ has no member named ‘ppc’ bler_f ‘jit_bler_f’ was not declared in this scope bler_d ‘JNCm’ was not declared in this scope ‘union jit_state::pointer’ has no member named ‘ppc’ bgtr_f ‘jit_bgtr_f’ was not declared in this scope bgtr_d macro "JZm" passed 4 arguments, but takes just 1 ‘union jit_state::pointer’ has no member named ‘ppc’ bger_f ‘jit_bger_f’ was not declared in this scope bger_d ‘JNCm’ was not declared in this scope ‘union jit_state::pointer’ has no member named ‘ppc’ beqr_f ‘jit_beqr_f’ was not declared in this scope beqr_d macro "JZm" passed 4 arguments, but takes just 1 ‘union jit_state::pointer’ has no member named ‘ppc’ bner_f ‘jit_bner_f’ was not declared in this scope bner_d macro "JNZm" passed 4 arguments, but takes just 1 ‘union jit_state::pointer’ has no member named ‘ppc’ bunltr_f ‘jit_bunltr_f’ was not declared in this scope bunltr_d ‘JCm’ was not declared in this scope ‘union jit_state::pointer’ has no member named ‘ppc’ bunler_f ‘jit_bunler_f’ was not declared in this scope bunler_d macro "JNZm" passed 4 arguments, but takes just 1 ‘union jit_state::pointer’ has no member named ‘ppc’ bungtr_f ‘jit_bungtr_f’ was not declared in this scope bungtr_d ‘JCm’ was not declared in this scope ‘union jit_state::pointer’ has no member named ‘ppc’ bunger_f ‘jit_bunger_f’ was not declared in this scope bunger_d macro "JNZm" passed 4 arguments, but takes just 1 ‘union jit_state::pointer’ has no member named ‘ppc’ buneqr_f ‘jit_buneqr_f’ was not declared in this scope buneqr_d ‘JCm’ was not declared in this scope ‘union jit_state::pointer’ has no member named ‘ppc’ bltgtr_f ‘jit_bltgtr_f’ was not declared in this scope bltgtr_d ‘JNCm’ was not declared in this scope ‘union jit_state::pointer’ has no member named ‘ppc’ bordr_f ‘jit_bordr_f’ was not declared in this scope bordr_d ‘JNCm’ was not declared in this scope ‘union jit_state::pointer’ has no member named ‘ppc’ bunordr_f ‘jit_bunordr_f’ was not declared in this scope bunordr_d ‘JCm’ was not declared in this scope ‘union jit_state::pointer’ has no member named ‘ppc’ == Transfer == roundr_f_l ‘jit_roundr_f_l’ was not declared in this scope roundr_d_l ‘jit_roundr_d_l’ was not declared in this scope truncr_f_l ‘jit_truncr_f_l’ was not declared in this scope truncr_d_l ‘jit_truncr_d_l’ was not declared in this scope floorr_f_l ‘jit_floorr_f_l’ was not declared in this scope floorr_d_l ‘jit_floorr_d_l’ was not declared in this scope ceilr_f_l ‘jit_ceilr_f_l’ was not declared in this scope ceilr_d_l ‘jit_ceilr_d_l’ was not declared in this scope == Unary == notr_c ‘jit_xori_c’ was not declared in this scope notr_uc ‘jit_xori_c’ was not declared in this scope notr_s ‘jit_xori_s’ was not declared in this scope notr_us ‘jit_xori_s’ was not declared in this scope _______________________________________________ Lightning mailing list Lightning@... http://lists.gnu.org/mailman/listinfo/lightning |
|
|
Re: Runtime assembler in C++Actually, I was using an older version from CVS. I checked out the git
repository now and many were fixed. I will create new lists later. One question: leaf (2); int ofs = arg_i (); getarg_i (R0, ofs); ofs = arg_i (); getarg_i (R1, ofs); addr_i (RET, R0, R1); ret (); Can this be written as: leaf (2); getarg_i (R0, arg_i ()); getarg_i (R1, arg_i ()); addr_i (RET, R0, R1); ret (); In all cases, or are there cases where this does not work? I am thinking of the function evaluation with functions returning immediates. Regards, Pippijn _______________________________________________ Lightning mailing list Lightning@... http://lists.gnu.org/mailman/listinfo/lightning |
|
|
Re: Runtime assembler in C++Pippijn van Steenhoven wrote:
> Actually, I was using an older version from CVS. I checked out the git > repository now and many were fixed. I will create new lists later. Thanks! > leaf (2); > int ofs = arg_i (); > getarg_i (R0, ofs); > ofs = arg_i (); > getarg_i (R1, ofs); > addr_i (RET, R0, R1); > ret (); > > Can this be written as: > > leaf (2); > getarg_i (R0, arg_i ()); > getarg_i (R1, arg_i ()); > addr_i (RET, R0, R1); > ret (); > > In all cases, or are there cases where this does not work? I am > thinking of the function evaluation with functions returning > immediates. It might cause double evaluation of macro arguments. If everything's wrapped (as you did) in a C++ class, it's not a problem. Paolo _______________________________________________ Lightning mailing list Lightning@... http://lists.gnu.org/mailman/listinfo/lightning |
| Free embeddable forum powered by Nabble | Forum Help |