[m-rev.] for review: x86-64 instructions and output files

Zoltan Somogyi zs at csse.unimelb.edu.au
Mon Jan 15 17:39:43 AEDT 2007


On 15-Jan-2007, Fransiska Nathania HANDOKO <fhandoko at students.csse.unimelb.edu.au> wrote:
> +:- type x86_64_instruction
> +    --->    x86_64_instr(
> +                x86_64_instr_name   :: x86_64_op,
> +                x86_64_comment      :: string
> +            ).
> +
> +:- type label_name == string.
> +
> +:- type x86_64_instr
> +    --->    comment(string)
> +    ;       label(label_name)
> +    ;       directives(list(pseudo_op))

> +    ;       instrs(list(x86_64_instruction)).

Why do you not directive(pseudo_op) or instr(x86_64_instruction)?
And why not just list all the pseudo-ops and all the x86_64_instructions
as function symbols of this type?

Don't change this now, but think about it.

> +    % Pseudo op for x86_64. Also called assembler directive.
> +    %
> +:- type pseudo_op
> +    --->    abort
> +            % stop the assembly immediately.

It looks like you added all the pseuso-ops listed in the manual. However,
we will need only a subset of these. (I strongly doubt we will ever need
abort, for instance.) Including them makes it harder to write the code to
output your data structure, but that task is already done.

> +    ;       else_
> +            % As in 'if-then-else' conditional expression.

Many of the names of these pseudo-ops and instructions will conflict with
the names of Mercury constructs. Our standard solution is to give all the
function symbols in such a type a unique prefix, like x86_64_pseudo or
x86_64_op.

> +    % General purpose registers on the x86_64.
> +    % Details on amd64-prog-man-vol1 manual p27.
> +    %
> +:- type gp_reg
> +    --->    rax
> +    ;       rbx
> +    ;       rcx
> +    ;       rdx
> +    ;       rbp
> +    ;       rsi
> +    ;       rdi
> +    ;       rsp
> +    ;       r8
> +    ;       r9
> +    ;       r10
> +    ;       r11
> +    ;       r12
> +    ;       r13
> +    ;       r14
> +    ;       r15.

I think it would be much easier to write the code generator if this was
changed to something like

:- type gp_reg
	--->	gp_reg(int).

where the int has to be <= 15 at output, (but can be > 15 initially).

> +    ;       cmovnle(
> +                cmovnle_src     :: reg_or_mem_ref_op,
> +                cmovnle_dest    :: gp_reg
> +            )
> +            % Moves if not less or equal (ZF = 0 or SF = OF).
> +            % Details on amd64-prog-man-vol3 manual p103.
> +
> +    ;       cmovg(
> +                cmovg_src       :: reg_or_mem_ref_op,
> +                cmovg_dest      :: gp_reg
> +            )
> +            % Moves if greater (ZF = 0 or SF = OF).
> +            % Details on amd64-prog-man-vol3 manual p103.

You probably want to factor these differently, with these two and some others
all rolled into a single function symbol with a third argument saying what
comparison operation you want. The intermediate representation doesn't have
to correspond one-to-one to the final code. Similarly for other groups of
instructions, e.g. conditional jumps.

Otherwise, it looks good.

Zoltan.
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list