[m-rev.] for review: streamify x86_64 instruction output
Julien Fischer
juliensf at csse.unimelb.edu.au
Wed Feb 7 20:07:37 AEDT 2007
For review by Fransiska.
Estimated hours taken: 1.5
Branches: main
Allow x86_64 assembler instructions to be written to streams. The
intention is that we should use the code in x86_64_out to generate
both debugging output and also to write the contents of the __asm__
blocks in the generated C/asm code.
compiler/x86_64_out.m:
Streamify the output predicates in this module so that they
work with (almost) arbitrary string writers rather than writing
to stdout. (The "almost" bit is explained in the comment at the
top of the module.)
Fix some comments in a few spots.
compiler/llds_to_x86_64_out.m:
Make the predicates in this module take an argument of type
of io.output_stream.
Fix indentation.
compiler/mercury_compile.m:
Conform to the above changes.
Julien.
Index: compiler/llds_to_x86_64_out.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/llds_to_x86_64_out.m,v
retrieving revision 1.1
diff -u -r1.1 llds_to_x86_64_out.m
--- compiler/llds_to_x86_64_out.m 5 Feb 2007 22:30:33 -0000 1.1
+++ compiler/llds_to_x86_64_out.m 7 Feb 2007 08:58:21 -0000
@@ -24,7 +24,8 @@
%-----------------------------------------------------------------------------%
-:- pred output_x86_64_asm(list(x86_64_procedure)::in, io::di, io::uo) is det.
+:- pred output_x86_64_asm(io.output_stream::in, list(x86_64_procedure)::in,
+ io::di, io::uo) is det.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
@@ -34,24 +35,26 @@
:- import_module ll_backend.llds_to_x86_64.
:- import_module ll_backend.x86_64_out.
-output_x86_64_asm(AsmProcs, !IO) :-
- output_asm_proc_list(AsmProcs, !IO).
-
-
-:- pred output_asm_proc_list(list(x86_64_procedure)::in, io::di, io::uo) is det.
+%-----------------------------------------------------------------------------%
-output_asm_proc_list([], !IO).
-output_asm_proc_list([AsmProc | AsmProcs], !IO) :-
- output_asm_instr_list(AsmProc ^ x86_64_code, !IO),
- output_asm_proc_list(AsmProcs, !IO).
+output_x86_64_asm(Stream, AsmProcs, !IO) :-
+ output_asm_proc_list(Stream, AsmProcs, !IO).
-:- pred output_asm_instr_list(list(x86_64_instruction)::in, io::di, io::uo)
- is det.
+:- pred output_asm_proc_list(io.output_stream::in,
+ list(x86_64_procedure)::in, io::di, io::uo) is det.
-output_asm_instr_list([], !IO).
-output_asm_instr_list([AsmInstr | AsmInstrs], !IO) :-
- output_x86_64_instruction(AsmInstr, !IO),
- output_asm_instr_list(AsmInstrs, !IO).
+output_asm_proc_list(_, [], !IO).
+output_asm_proc_list(Stream, [AsmProc | AsmProcs], !IO) :-
+ output_asm_instr_list(Stream, AsmProc ^ x86_64_code, !IO),
+ output_asm_proc_list(Stream, AsmProcs, !IO).
+
+:- pred output_asm_instr_list(io.output_stream::in,
+ list(x86_64_instruction)::in, io::di, io::uo) is det.
+
+output_asm_instr_list(_, [], !IO).
+output_asm_instr_list(Stream, [AsmInstr | AsmInstrs], !IO) :-
+ output_x86_64_instruction(Stream, AsmInstr, !IO),
+ output_asm_instr_list(Stream, AsmInstrs, !IO).
%----------------------------------------------------------------------------%
:- end_module llds_to_x86_64_out.
Index: compiler/mercury_compile.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mercury_compile.m,v
retrieving revision 1.427
diff -u -r1.427 mercury_compile.m
--- compiler/mercury_compile.m 5 Feb 2007 22:30:33 -0000 1.427
+++ compiler/mercury_compile.m 7 Feb 2007 08:59:15 -0000
@@ -1645,16 +1645,15 @@
)
;
Target = target_x86_64,
-% backend_pass(!HLDS, GlobalData, LLDS, !DumpInfo, !IO),
- backend_pass(!HLDS, _, LLDS, !DumpInfo, !IO),
+ backend_pass(!HLDS, _GlobalData, LLDS, !DumpInfo, !IO),
% XXX Eventually we will call the LLDS->x86_64 asm code
% generator here and then output the assembler. At the moment
% we just output the LLDS as C code.
llds_to_x86_64_asm(!.HLDS, LLDS, X86_64_Asm),
- output_x86_64_asm(X86_64_Asm, !IO),
- % need to output x86_64_Asm
- %output_pass(!.HLDS, GlobalData, LLDS, ModuleName,
- % _CompileErrors, _, !IO),
+ % XXX This should eventually be written to a file rather
+ % than stdout.
+ io.stdout_stream(Stdout, !IO),
+ output_x86_64_asm(Stdout, X86_64_Asm, !IO),
FactTableBaseFiles = []
),
recompilation.usage.write_usage_file(!.HLDS, NestedSubModules,
Index: compiler/x86_64_out.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/x86_64_out.m,v
retrieving revision 1.2
diff -u -r1.2 x86_64_out.m
--- compiler/x86_64_out.m 5 Feb 2007 22:30:34 -0000 1.2
+++ compiler/x86_64_out.m 7 Feb 2007 08:49:25 -0000
@@ -9,7 +9,10 @@
% File: x86_64_out.m.
% Main author: fhandoko.
%
-% This module defines the routines for printing out x86_64 instructions.
+% This module defines routines for writing x86_64 assembler instructions
+% to string writer streams that are attached to the I/O state.
+% (There's no particularly good reason for this latter restriction so
+% it can safely be dropped if necessary.)
%
%-----------------------------------------------------------------------------%
@@ -19,15 +22,21 @@
:- import_module ll_backend.x86_64_instrs.
:- import_module io.
+:- import_module stream.
%-----------------------------------------------------------------------------%
-:- pred output_x86_64_instruction(x86_64_instruction::in,
- io::di, io::uo) is det.
+ % Output an x86_64_instruction to the given stream.
+ %
+:- pred output_x86_64_instruction(Stream::in, x86_64_instruction::in,
+ io::di, io::uo) is det <= stream.writer(Stream, string, io).
+ % XXX this is misnamed: it should be operand_to_string.
+ %
:- pred operand_type(operand::in, string::out) is det.
%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
:- implementation.
@@ -38,181 +47,185 @@
:- import_module int.
:- import_module list.
:- import_module maybe.
+:- import_module stream.string_writer.
:- import_module string.
:- import_module type_desc.
%-----------------------------------------------------------------------------%
-%-----------------------------------------------------------------------------%
%
-% Output x86_64 pseudo-op.
+% Output x86_64 pseudo-op for GNU as
%
-:- pred output_x86_64_pseudo_op(pseudo_op::in, io::di, io::uo) is det.
+:- pred output_x86_64_pseudo_op(Stream::in, pseudo_op::in, io::di, io::uo)
+ is det <= stream.writer(Stream, string, io).
-output_x86_64_pseudo_op(abort, !IO) :-
- io.write_string("\t.abort\n", !IO).
-output_x86_64_pseudo_op(align(Bytes, FillVal, SkipBytes), !IO) :-
- output_pseudo_op_with_int_args(".align", Bytes, FillVal, SkipBytes, !IO).
-output_x86_64_pseudo_op(ascii(Literals), !IO) :-
- output_pseudo_op_str_args(".ascii", Literals, !IO).
-output_x86_64_pseudo_op(asciiz(Literals), !IO) :-
- output_pseudo_op_str_args(".asciiz", Literals, !IO).
-output_x86_64_pseudo_op(balign(Bytes, FillVal, SkipBytes), !IO) :-
- output_pseudo_op_with_int_args(".balign", Bytes, FillVal, SkipBytes, !IO).
-output_x86_64_pseudo_op(byte(ExprList), !IO) :-
- output_pseudo_op_str_args(".byte", ExprList, !IO).
-output_x86_64_pseudo_op(comm(Symbol, Length, Align0), !IO) :-
- io.write_string("\t.comm\t" ++ Symbol ++ ",", !IO),
- io.write_int(Length, !IO),
+output_x86_64_pseudo_op(Stream, abort, !IO) :-
+ put(Stream, "\t.abort\n", !IO).
+output_x86_64_pseudo_op(Stream, align(Bytes, FillVal, SkipBytes), !IO) :-
+ output_pseudo_op_with_int_args(Stream, ".align", Bytes, FillVal,
+ SkipBytes, !IO).
+output_x86_64_pseudo_op(Stream, ascii(Literals), !IO) :-
+ output_pseudo_op_str_args(Stream, ".ascii", Literals, !IO).
+output_x86_64_pseudo_op(Stream, asciiz(Literals), !IO) :-
+ output_pseudo_op_str_args(Stream, ".asciiz", Literals, !IO).
+output_x86_64_pseudo_op(Stream, balign(Bytes, FillVal, SkipBytes), !IO) :-
+ output_pseudo_op_with_int_args(Stream, ".balign", Bytes, FillVal,
+ SkipBytes, !IO).
+output_x86_64_pseudo_op(Stream, byte(ExprList), !IO) :-
+ output_pseudo_op_str_args(Stream, ".byte", ExprList, !IO).
+output_x86_64_pseudo_op(Stream, comm(Symbol, Length, Align0), !IO) :-
+ put(Stream, "\t.comm\t" ++ Symbol ++ ",", !IO),
+ put_int(Stream, Length, !IO),
(
Align0 = yes(Align1),
- io.write_string(",", !IO),
- io.write_int(Align1, !IO)
+ put(Stream, ",", !IO),
+ put_int(Stream, Align1, !IO)
;
Align0 = no
),
- io.write_string("\n", !IO).
-output_x86_64_pseudo_op(data(Subsection0), !IO) :-
- io.write_string("\t.data\t", !IO),
+ put(Stream, "\n", !IO).
+output_x86_64_pseudo_op(Stream, data(Subsection0), !IO) :-
+ put(Stream, "\t.data\t", !IO),
(
Subsection0 = yes(Subsection1),
- io.write_int(Subsection1, !IO)
+ put_int(Stream, Subsection1, !IO)
;
Subsection0 = no
),
- io.write_string("\n", !IO).
-output_x86_64_pseudo_op(desc(Symbol, AbsExpr), !IO) :-
- io.write_string("\t.desc\t" ++ Symbol ++ "," ++ AbsExpr ++ "\n", !IO).
-output_x86_64_pseudo_op(def(Name), !IO) :-
- io.write_string("\t.def\t" ++ Name ++ "\n", !IO).
-output_x86_64_pseudo_op(dim, !IO) :-
- io.write_string("\t.dim\n", !IO).
-output_x86_64_pseudo_op(double(NumList), !IO) :-
- output_pseudo_op_float_args(".double", NumList, !IO).
-output_x86_64_pseudo_op(eject, !IO) :-
- io.write_string("\t.eject\n", !IO).
-output_x86_64_pseudo_op(x86_64_pseudo_else, !IO) :-
- io.write_string("\t.else\n", !IO).
-output_x86_64_pseudo_op(elseif, !IO) :-
- io.write_string("\t.elseif\n", !IO).
-output_x86_64_pseudo_op(end, !IO) :-
- io.write_string("\t.end\n", !IO).
-output_x86_64_pseudo_op(endef, !IO) :-
- io.write_string("\t.endef\n", !IO).
-output_x86_64_pseudo_op(endfunc, !IO) :-
- io.write_string("\t.endfunc\n", !IO).
-output_x86_64_pseudo_op(endif, !IO) :-
- io.write_string("\t.endif\n", !IO).
-output_x86_64_pseudo_op(endm, !IO) :-
- io.write_string("\t.endm\n", !IO).
-output_x86_64_pseudo_op(equ(Symbol, Expr), !IO) :-
- io.write_string("\t.equ\t" ++ Symbol ++ "," ++ Expr ++ "\n", !IO).
-output_x86_64_pseudo_op(equiv(Symbol, Expr), !IO) :-
- io.write_string("\t.equiv\t" ++ Symbol ++ "," ++ Expr ++ "\n", !IO).
-output_x86_64_pseudo_op(err, !IO) :-
- io.write_string("\t.err\n", !IO).
-output_x86_64_pseudo_op(exitm, !IO) :-
- io.write_string("\t.exitm\n", !IO).
-output_x86_64_pseudo_op(extern, !IO) :-
- io.write_string("\t.extern\n", !IO).
-output_x86_64_pseudo_op(fail_(Expr), !IO) :-
- io.write_string("\t.fail\t" ++ Expr++ "\n", !IO).
-output_x86_64_pseudo_op(file(Name), !IO) :-
- io.write_string("\t.file\t\"" ++ Name ++ "\"\n", !IO).
-output_x86_64_pseudo_op(fill(Repeat, Size, Val), !IO) :-
- output_pseudo_op_with_int_args(".repeat", Repeat, Size, Val, !IO).
-output_x86_64_pseudo_op(float(NumList), !IO) :-
- output_pseudo_op_float_args(".float", NumList, !IO).
-output_x86_64_pseudo_op(func_(Name, Label), !IO) :-
- io.write_string("\t.func\t" ++ Name ++ "," ++ Label ++ "\n", !IO).
-output_x86_64_pseudo_op(global(Symbol), !IO) :-
- io.write_string("\t.global\t" ++ Symbol ++ "\n", !IO).
-output_x86_64_pseudo_op(globl(Symbol), !IO) :-
- io.write_string("\t.globl\t" ++ Symbol ++ "\n", !IO).
-output_x86_64_pseudo_op(hidden(Name), !IO) :-
- io.write_string("\t.hidden\t" ++ Name ++ "\n", !IO).
-output_x86_64_pseudo_op(hword(ExprList), !IO) :-
- output_pseudo_op_str_args(".hword", ExprList, !IO).
-output_x86_64_pseudo_op(ident, !IO) :-
- io.write_string("\t.ident\n", !IO).
-output_x86_64_pseudo_op(x86_64_pseudo_if(Expr), !IO) :-
- io.write_string("\t.if\t" ++ Expr ++ "\n", !IO).
-output_x86_64_pseudo_op(ifdef(Symbol), !IO) :-
- io.write_string("\t.ifdef\t" ++ Symbol ++ "\n", !IO).
-output_x86_64_pseudo_op(ifc(Str1, Str2), !IO) :-
- io.write_string("\t.ifc\t" ++ Str1 ++ "," ++ Str2 ++ "\n", !IO).
-output_x86_64_pseudo_op(ifeq(Expr), !IO) :-
- io.write_string("\t.ifeq\t" ++ Expr ++ "\n", !IO).
-output_x86_64_pseudo_op(ifge(Expr), !IO) :-
- io.write_string("\t.ifge\t" ++ Expr ++ "\n", !IO).
-output_x86_64_pseudo_op(ifgt(Expr), !IO) :-
- io.write_string("\t.ifgt\t" ++ Expr ++ "\n", !IO).
-output_x86_64_pseudo_op(ifle(Expr), !IO) :-
- io.write_string("\t.ifle\t" ++ Expr ++ "\n", !IO).
-output_x86_64_pseudo_op(iflt(Expr), !IO) :-
- io.write_string("\t.iflt\t" ++ Expr ++ "\n", !IO).
-output_x86_64_pseudo_op(ifnc(Str1, Str2), !IO) :-
- io.write_string("\t.ifnc\t" ++ Str1 ++ "," ++ Str2 ++ "\n", !IO).
-output_x86_64_pseudo_op(ifndef(Symbol), !IO) :-
- io.write_string("\t.ifndef\t" ++ Symbol ++ "\n", !IO).
-output_x86_64_pseudo_op(ifnotdef(Symbol), !IO) :-
- io.write_string("\t.ifnotdef\t" ++ Symbol ++ "\n", !IO).
-output_x86_64_pseudo_op(ifne(Expr), !IO) :-
- io.write_string("\t.ifne\t" ++ Expr ++ "\n", !IO).
-output_x86_64_pseudo_op(ifnes(Str1, Str2), !IO) :-
- io.write_string("\t.ifnes\t" ++ Str1 ++ "," ++ Str2 ++ "\n", !IO).
-output_x86_64_pseudo_op(include(File), !IO) :-
- io.write_string("\t.include\t" ++ "\"" ++ File ++ "\"\n", !IO).
-output_x86_64_pseudo_op(int(ExprList), !IO) :-
- output_pseudo_op_str_args(".int", ExprList, !IO).
-output_x86_64_pseudo_op(internal(Name), !IO) :-
- io.write_string("\t.internal\t" ++ Name ++ "\n", !IO).
-output_x86_64_pseudo_op(lcomm(Symbol, Length), !IO) :-
- io.write_string("\tlcomm\t" ++ Symbol, !IO),
- io.write_int(Length, !IO),
- io.write_string("\n", !IO).
-output_x86_64_pseudo_op(line(LineNum), !IO) :-
- io.write_string("\t.line\t", !IO),
- io.write_int(LineNum, !IO),
- io.write_string("\n", !IO).
-output_x86_64_pseudo_op(list, !IO) :-
- io.write_string("\t.list\n", !IO).
-output_x86_64_pseudo_op(long(ExprList), !IO) :-
- output_pseudo_op_str_args(".long", ExprList, !IO).
-output_x86_64_pseudo_op(macro, !IO) :-
- io.write_string("\t.macro\n", !IO).
-output_x86_64_pseudo_op(nolist, !IO) :-
- io.write_string("\t.nolist\n", !IO).
-output_x86_64_pseudo_op(p2align(PowBit, FillVal, SkipBytes), !IO) :-
- output_pseudo_op_with_int_args(".p2align", PowBit, FillVal, SkipBytes, !IO).
-output_x86_64_pseudo_op(popsection, !IO) :-
- io.write_string("\t.popsection\n", !IO).
-output_x86_64_pseudo_op(previous, !IO) :-
- io.write_string("\t.previous\n", !IO).
-output_x86_64_pseudo_op(print(Str), !IO) :-
- io.write_string("\t.print\t" ++ Str ++ "\n", !IO).
-output_x86_64_pseudo_op(protected(Name), !IO) :-
- io.write_string("\t.protected\t" ++ Name ++ "\n", !IO).
-output_x86_64_pseudo_op(psize(Lines, Cols), !IO) :-
- output_pseudo_op_with_int_args(".psize", Lines, Cols, no, !IO).
-output_x86_64_pseudo_op(purgem(Name), !IO) :-
- io.write_string("\t.purgem\t" ++ Name ++ "\n", !IO).
-output_x86_64_pseudo_op(pushsection(Name, Subsection), !IO) :-
- io.write_string("\t.pushsection\t" ++ Name, !IO),
- io.write_int(Subsection, !IO),
- io.write_string("\n", !IO).
-output_x86_64_pseudo_op(quad(BigNumList), !IO) :-
- output_pseudo_op_str_args("\t.quad\t", BigNumList, !IO).
-output_x86_64_pseudo_op(rept(Count), !IO) :-
- io.write_string("\t.rept\t", !IO),
- io.write_int(Count, !IO),
- io.write_string("\n", !IO).
-output_x86_64_pseudo_op(sbttl(SubHeading), !IO) :-
- io.write_string("\t.sbttl\t" ++ "\"" ++ SubHeading ++ "\"\n", !IO).
-output_x86_64_pseudo_op(scl(Class), !IO) :-
- io.write_string("\t.scl\t" ++ Class ++ "\n", !IO).
-output_x86_64_pseudo_op(section(Name, Flags0, Type0, EntSize0), !IO) :-
- io.write_string("\t.section\t" ++ Name, !IO),
+ put(Stream, "\n", !IO).
+output_x86_64_pseudo_op(Stream, desc(Symbol, AbsExpr), !IO) :-
+ put(Stream, "\t.desc\t" ++ Symbol ++ "," ++ AbsExpr ++ "\n", !IO).
+output_x86_64_pseudo_op(Stream, def(Name), !IO) :-
+ put(Stream, "\t.def\t" ++ Name ++ "\n", !IO).
+output_x86_64_pseudo_op(Stream, dim, !IO) :-
+ put(Stream, "\t.dim\n", !IO).
+output_x86_64_pseudo_op(Stream, double(NumList), !IO) :-
+ output_pseudo_op_float_args(Stream, ".double", NumList, !IO).
+output_x86_64_pseudo_op(Stream, eject, !IO) :-
+ put(Stream, "\t.eject\n", !IO).
+output_x86_64_pseudo_op(Stream, x86_64_pseudo_else, !IO) :-
+ put(Stream, "\t.else\n", !IO).
+output_x86_64_pseudo_op(Stream, elseif, !IO) :-
+ put(Stream, "\t.elseif\n", !IO).
+output_x86_64_pseudo_op(Stream, end, !IO) :-
+ put(Stream, "\t.end\n", !IO).
+output_x86_64_pseudo_op(Stream, endef, !IO) :-
+ put(Stream, "\t.endef\n", !IO).
+output_x86_64_pseudo_op(Stream, endfunc, !IO) :-
+ put(Stream, "\t.endfunc\n", !IO).
+output_x86_64_pseudo_op(Stream, endif, !IO) :-
+ put(Stream, "\t.endif\n", !IO).
+output_x86_64_pseudo_op(Stream, endm, !IO) :-
+ put(Stream, "\t.endm\n", !IO).
+output_x86_64_pseudo_op(Stream, equ(Symbol, Expr), !IO) :-
+ put(Stream, "\t.equ\t" ++ Symbol ++ "," ++ Expr ++ "\n", !IO).
+output_x86_64_pseudo_op(Stream, equiv(Symbol, Expr), !IO) :-
+ put(Stream, "\t.equiv\t" ++ Symbol ++ "," ++ Expr ++ "\n", !IO).
+output_x86_64_pseudo_op(Stream, err, !IO) :-
+ put(Stream, "\t.err\n", !IO).
+output_x86_64_pseudo_op(Stream, exitm, !IO) :-
+ put(Stream, "\t.exitm\n", !IO).
+output_x86_64_pseudo_op(Stream, extern, !IO) :-
+ put(Stream, "\t.extern\n", !IO).
+output_x86_64_pseudo_op(Stream, fail_(Expr), !IO) :-
+ put(Stream, "\t.fail\t" ++ Expr++ "\n", !IO).
+output_x86_64_pseudo_op(Stream, file(Name), !IO) :-
+ put(Stream, "\t.file\t\"" ++ Name ++ "\"\n", !IO).
+output_x86_64_pseudo_op(Stream, fill(Repeat, Size, Val), !IO) :-
+ output_pseudo_op_with_int_args(Stream, ".repeat", Repeat, Size, Val, !IO).
+output_x86_64_pseudo_op(Stream, float(NumList), !IO) :-
+ output_pseudo_op_float_args(Stream, ".float", NumList, !IO).
+output_x86_64_pseudo_op(Stream, func_(Name, Label), !IO) :-
+ put(Stream, "\t.func\t" ++ Name ++ "," ++ Label ++ "\n", !IO).
+output_x86_64_pseudo_op(Stream, global(Symbol), !IO) :-
+ put(Stream, "\t.global\t" ++ Symbol ++ "\n", !IO).
+output_x86_64_pseudo_op(Stream, globl(Symbol), !IO) :-
+ put(Stream, "\t.globl\t" ++ Symbol ++ "\n", !IO).
+output_x86_64_pseudo_op(Stream, hidden(Name), !IO) :-
+ put(Stream, "\t.hidden\t" ++ Name ++ "\n", !IO).
+output_x86_64_pseudo_op(Stream, hword(ExprList), !IO) :-
+ output_pseudo_op_str_args(Stream, ".hword", ExprList, !IO).
+output_x86_64_pseudo_op(Stream, ident, !IO) :-
+ put(Stream, "\t.ident\n", !IO).
+output_x86_64_pseudo_op(Stream, x86_64_pseudo_if(Expr), !IO) :-
+ put(Stream, "\t.if\t" ++ Expr ++ "\n", !IO).
+output_x86_64_pseudo_op(Stream, ifdef(Symbol), !IO) :-
+ put(Stream, "\t.ifdef\t" ++ Symbol ++ "\n", !IO).
+output_x86_64_pseudo_op(Stream, ifc(Str1, Str2), !IO) :-
+ put(Stream, "\t.ifc\t" ++ Str1 ++ "," ++ Str2 ++ "\n", !IO).
+output_x86_64_pseudo_op(Stream, ifeq(Expr), !IO) :-
+ put(Stream, "\t.ifeq\t" ++ Expr ++ "\n", !IO).
+output_x86_64_pseudo_op(Stream, ifge(Expr), !IO) :-
+ put(Stream, "\t.ifge\t" ++ Expr ++ "\n", !IO).
+output_x86_64_pseudo_op(Stream, ifgt(Expr), !IO) :-
+ put(Stream, "\t.ifgt\t" ++ Expr ++ "\n", !IO).
+output_x86_64_pseudo_op(Stream, ifle(Expr), !IO) :-
+ put(Stream, "\t.ifle\t" ++ Expr ++ "\n", !IO).
+output_x86_64_pseudo_op(Stream, iflt(Expr), !IO) :-
+ put(Stream, "\t.iflt\t" ++ Expr ++ "\n", !IO).
+output_x86_64_pseudo_op(Stream, ifnc(Str1, Str2), !IO) :-
+ put(Stream, "\t.ifnc\t" ++ Str1 ++ "," ++ Str2 ++ "\n", !IO).
+output_x86_64_pseudo_op(Stream, ifndef(Symbol), !IO) :-
+ put(Stream, "\t.ifndef\t" ++ Symbol ++ "\n", !IO).
+output_x86_64_pseudo_op(Stream, ifnotdef(Symbol), !IO) :-
+ put(Stream, "\t.ifnotdef\t" ++ Symbol ++ "\n", !IO).
+output_x86_64_pseudo_op(Stream, ifne(Expr), !IO) :-
+ put(Stream, "\t.ifne\t" ++ Expr ++ "\n", !IO).
+output_x86_64_pseudo_op(Stream, ifnes(Str1, Str2), !IO) :-
+ put(Stream, "\t.ifnes\t" ++ Str1 ++ "," ++ Str2 ++ "\n", !IO).
+output_x86_64_pseudo_op(Stream, include(File), !IO) :-
+ put(Stream, "\t.include\t" ++ "\"" ++ File ++ "\"\n", !IO).
+output_x86_64_pseudo_op(Stream, int(ExprList), !IO) :-
+ output_pseudo_op_str_args(Stream, ".int", ExprList, !IO).
+output_x86_64_pseudo_op(Stream, internal(Name), !IO) :-
+ put(Stream, "\t.internal\t" ++ Name ++ "\n", !IO).
+output_x86_64_pseudo_op(Stream, lcomm(Symbol, Length), !IO) :-
+ put(Stream, "\tlcomm\t" ++ Symbol, !IO),
+ put_int(Stream, Length, !IO),
+ put(Stream, "\n", !IO).
+output_x86_64_pseudo_op(Stream, line(LineNum), !IO) :-
+ put(Stream, "\t.line\t", !IO),
+ put_int(Stream, LineNum, !IO),
+ put(Stream, "\n", !IO).
+output_x86_64_pseudo_op(Stream, list, !IO) :-
+ put(Stream, "\t.list\n", !IO).
+output_x86_64_pseudo_op(Stream, long(ExprList), !IO) :-
+ output_pseudo_op_str_args(Stream, ".long", ExprList, !IO).
+output_x86_64_pseudo_op(Stream, macro, !IO) :-
+ put(Stream, "\t.macro\n", !IO).
+output_x86_64_pseudo_op(Stream, nolist, !IO) :-
+ put(Stream, "\t.nolist\n", !IO).
+output_x86_64_pseudo_op(Stream, p2align(PowBit, FillVal, SkipBytes), !IO) :-
+ output_pseudo_op_with_int_args(Stream, ".p2align", PowBit, FillVal,
+ SkipBytes, !IO).
+output_x86_64_pseudo_op(Stream, popsection, !IO) :-
+ put(Stream, "\t.popsection\n", !IO).
+output_x86_64_pseudo_op(Stream, previous, !IO) :-
+ put(Stream, "\t.previous\n", !IO).
+output_x86_64_pseudo_op(Stream, print(Str), !IO) :-
+ put(Stream, "\t.print\t" ++ Str ++ "\n", !IO).
+output_x86_64_pseudo_op(Stream, protected(Name), !IO) :-
+ put(Stream, "\t.protected\t" ++ Name ++ "\n", !IO).
+output_x86_64_pseudo_op(Stream, psize(Lines, Cols), !IO) :-
+ output_pseudo_op_with_int_args(Stream, ".psize", Lines, Cols, no, !IO).
+output_x86_64_pseudo_op(Stream, purgem(Name), !IO) :-
+ put(Stream, "\t.purgem\t" ++ Name ++ "\n", !IO).
+output_x86_64_pseudo_op(Stream, pushsection(Name, Subsection), !IO) :-
+ put(Stream, "\t.pushsection\t" ++ Name, !IO),
+ put_int(Stream, Subsection, !IO),
+ put(Stream, "\n", !IO).
+output_x86_64_pseudo_op(Stream, quad(BigNumList), !IO) :-
+ output_pseudo_op_str_args(Stream, "\t.quad\t", BigNumList, !IO).
+output_x86_64_pseudo_op(Stream, rept(Count), !IO) :-
+ put(Stream, "\t.rept\t", !IO),
+ put_int(Stream, Count, !IO),
+ put(Stream, "\n", !IO).
+output_x86_64_pseudo_op(Stream, sbttl(SubHeading), !IO) :-
+ put(Stream, "\t.sbttl\t" ++ "\"" ++ SubHeading ++ "\"\n", !IO).
+output_x86_64_pseudo_op(Stream, scl(Class), !IO) :-
+ put(Stream, "\t.scl\t" ++ Class ++ "\n", !IO).
+output_x86_64_pseudo_op(Stream, section(Name, Flags0, Type0, EntSize0), !IO) :-
+ put(Stream, "\t.section\t" ++ Name, !IO),
(
Flags0 = yes(Flags1),
check_section_flags_and_type(Flags1, Type0, Result0),
@@ -220,9 +233,9 @@
Result0 = yes,
Type0 = yes(Type1)
->
- io.write_string(",\"" ++ Flags1 ++ "\"", !IO),
+ put(Stream, ",\"" ++ Flags1 ++ "\"", !IO),
( check_pseudo_section_type(Type1) ->
- io.write_string("," ++ Type1, !IO)
+ put(Stream, "," ++ Type1, !IO)
;
unexpected(this_file, "output_x86_64_pseudo_op: section:"
++ " check_section_type unexpected")
@@ -236,77 +249,78 @@
),
(
EntSize0 = yes(EntSize1),
- io.write_string(",", !IO),
- io.write_int(EntSize1, !IO)
+ put(Stream, ",", !IO),
+ put_int(Stream, EntSize1, !IO)
;
EntSize0 = no
),
- io.write_string("\n", !IO).
-output_x86_64_pseudo_op(set(Symbol, Expr), !IO) :-
- io.write_string("\t.set\t" ++ Symbol ++ "," ++ Expr ++ "\n", !IO).
-output_x86_64_pseudo_op(short(ExprList), !IO) :-
- output_pseudo_op_str_args(".short", ExprList, !IO).
-output_x86_64_pseudo_op(single(FloatList), !IO) :-
- output_pseudo_op_float_args(".single", FloatList, !IO).
-output_x86_64_pseudo_op(size(Name, Expr), !IO) :-
- io.write_string("\t.size\t" ++ Name ++ "," ++ Expr ++ "\n", !IO).
-output_x86_64_pseudo_op(skip(Size, Val), !IO) :-
- output_pseudo_op_with_int_args(".skip", Size, Val, no, !IO).
-output_x86_64_pseudo_op(sleb128(ExprList), !IO) :-
- output_pseudo_op_str_args(".sleb128\t", ExprList, !IO).
-output_x86_64_pseudo_op(space(Size, Fill), !IO) :-
- output_pseudo_op_with_int_args(".space", Size, Fill, no, !IO).
-output_x86_64_pseudo_op(string(StrList), !IO) :-
- output_pseudo_op_str_args(".string", StrList, !IO).
-output_x86_64_pseudo_op(struct(Expr), !IO) :-
- io.write_string("\t.struct\t" ++ Expr ++ "\n", !IO).
-output_x86_64_pseudo_op(subsection(Name), !IO) :-
- io.write_string("\t.subsection\t" ++ Name ++ "\n", !IO).
-output_x86_64_pseudo_op(symver(Name, Alias), !IO) :-
- io.write_string("\t.symver\t" ++ Name ++ "," ++ Alias ++ "\n", !IO).
-output_x86_64_pseudo_op(tag(Name), !IO) :-
- io.write_string("\t.tag\t" ++ Name ++ "\n", !IO).
-output_x86_64_pseudo_op(text(Subsection0), !IO) :-
- io.write_string("\ttext\t", !IO),
+ put(Stream, "\n", !IO).
+output_x86_64_pseudo_op(Stream, set(Symbol, Expr), !IO) :-
+ put(Stream, "\t.set\t" ++ Symbol ++ "," ++ Expr ++ "\n", !IO).
+output_x86_64_pseudo_op(Stream, short(ExprList), !IO) :-
+ output_pseudo_op_str_args(Stream, ".short", ExprList, !IO).
+output_x86_64_pseudo_op(Stream, single(FloatList), !IO) :-
+ output_pseudo_op_float_args(Stream, ".single", FloatList, !IO).
+output_x86_64_pseudo_op(Stream, size(Name, Expr), !IO) :-
+ put(Stream, "\t.size\t" ++ Name ++ "," ++ Expr ++ "\n", !IO).
+output_x86_64_pseudo_op(Stream, skip(Size, Val), !IO) :-
+ output_pseudo_op_with_int_args(Stream, ".skip", Size, Val, no, !IO).
+output_x86_64_pseudo_op(Stream, sleb128(ExprList), !IO) :-
+ output_pseudo_op_str_args(Stream, ".sleb128\t", ExprList, !IO).
+output_x86_64_pseudo_op(Stream, space(Size, Fill), !IO) :-
+ output_pseudo_op_with_int_args(Stream, ".space", Size, Fill, no, !IO).
+output_x86_64_pseudo_op(Stream, string(StrList), !IO) :-
+ output_pseudo_op_str_args(Stream, ".string", StrList, !IO).
+output_x86_64_pseudo_op(Stream, struct(Expr), !IO) :-
+ put(Stream, "\t.struct\t" ++ Expr ++ "\n", !IO).
+output_x86_64_pseudo_op(Stream, subsection(Name), !IO) :-
+ put(Stream, "\t.subsection\t" ++ Name ++ "\n", !IO).
+output_x86_64_pseudo_op(Stream, symver(Name, Alias), !IO) :-
+ put(Stream, "\t.symver\t" ++ Name ++ "," ++ Alias ++ "\n", !IO).
+output_x86_64_pseudo_op(Stream, tag(Name), !IO) :-
+ put(Stream, "\t.tag\t" ++ Name ++ "\n", !IO).
+output_x86_64_pseudo_op(Stream, text(Subsection0), !IO) :-
+ put(Stream, "\ttext\t", !IO),
(
Subsection0 = yes(Subsection1),
- io.write_int(Subsection1, !IO)
+ put_int(Stream, Subsection1, !IO)
;
Subsection0 = no
),
- io.write_string("\n", !IO).
-output_x86_64_pseudo_op(title(Heading), !IO) :-
- io.write_string("\t.title\t" ++ Heading ++ "\n", !IO).
-output_x86_64_pseudo_op(x86_64_pseudo_type(Name, Desc), !IO) :-
+ put(Stream, "\n", !IO).
+output_x86_64_pseudo_op(Stream, title(Heading), !IO) :-
+ put(Stream, "\t.title\t" ++ Heading ++ "\n", !IO).
+output_x86_64_pseudo_op(Stream, x86_64_pseudo_type(Name, Desc), !IO) :-
( check_pseudo_type_desc(Desc) ->
- io.write_string("\t.type\t" ++ Name ++ "," ++ Desc ++ "\n", !IO)
+ put(Stream, "\t.type\t" ++ Name ++ "," ++ Desc ++ "\n", !IO)
;
unexpected(this_file, "output_x86_64_pseudo_op: x86_64_pseudo_type:"
++ " unexpected: check_pseudo_type_desc failed")
).
-output_x86_64_pseudo_op(uleb128(ExprList), !IO) :-
- output_pseudo_op_str_args(".uleb128", ExprList, !IO).
-output_x86_64_pseudo_op(val(Addr), !IO) :-
- io.write_string("\t.val\t" ++ Addr ++ "\n", !IO).
-output_x86_64_pseudo_op(version(Note), !IO) :-
- io.write_string("\t.version\t" ++ Note ++ "\n", !IO).
-output_x86_64_pseudo_op(weak(NameList), !IO) :-
- output_pseudo_op_str_args(".weak", NameList, !IO).
-output_x86_64_pseudo_op(word(ExprList), !IO) :-
- output_pseudo_op_str_args(".word", ExprList, !IO).
+output_x86_64_pseudo_op(Stream, uleb128(ExprList), !IO) :-
+ output_pseudo_op_str_args(Stream, ".uleb128", ExprList, !IO).
+output_x86_64_pseudo_op(Stream, val(Addr), !IO) :-
+ put(Stream, "\t.val\t" ++ Addr ++ "\n", !IO).
+output_x86_64_pseudo_op(Stream, version(Note), !IO) :-
+ put(Stream, "\t.version\t" ++ Note ++ "\n", !IO).
+output_x86_64_pseudo_op(Stream, weak(NameList), !IO) :-
+ output_pseudo_op_str_args(Stream, ".weak", NameList, !IO).
+output_x86_64_pseudo_op(Stream, word(ExprList), !IO) :-
+ output_pseudo_op_str_args(Stream, ".word", ExprList, !IO).
% Output pseudo-op name with 1, 2 or 3 integer arguments.
%
-:- pred output_pseudo_op_with_int_args(string::in, int::in, maybe(int)::in,
- maybe(int)::in, io::di, io::uo) is det.
-
-output_pseudo_op_with_int_args(OpName, Arg1, Arg2, Arg3, !IO) :-
- io.write_string("\t" ++ OpName ++ "\t", !IO),
- io.write_int(Arg1, !IO),
+:- pred output_pseudo_op_with_int_args(Stream::in, string::in, int::in,
+ maybe(int)::in, maybe(int)::in, io::di, io::uo)
+ is det <= stream.writer(Stream, string, io).
+
+output_pseudo_op_with_int_args(Stream, OpName, Arg1, Arg2, Arg3, !IO) :-
+ put(Stream, "\t" ++ OpName ++ "\t", !IO),
+ put_int(Stream, Arg1, !IO),
(
Arg2 = yes(Arg2Out),
- io.write_string(",", !IO),
- io.write_int(Arg2Out, !IO)
+ put(Stream, ",", !IO),
+ put_int(Stream, Arg2Out, !IO)
;
Arg2 = no
),
@@ -314,67 +328,71 @@
Arg3 = yes(Arg3Out),
(
Arg2 = no,
- io.write_string(",,", !IO),
- io.write_int(Arg3Out, !IO)
+ put(Stream, ",,", !IO),
+ put_int(Stream, Arg3Out, !IO)
;
Arg2 = yes(_),
- io.write_string(",", !IO),
- io.write_int(Arg3Out, !IO)
+ put(Stream, ",", !IO),
+ put_int(Stream, Arg3Out, !IO)
)
;
Arg3 = no
),
- io.write_string("\n", !IO).
+ put(Stream, "\n", !IO).
% Output pseudo-op having list of float as its argument.
%
-:- pred output_pseudo_op_float_args(string::in, list(float)::in,
- io::di, io::uo) is det.
+:- pred output_pseudo_op_float_args(Stream::in, string::in, list(float)::in,
+ io::di, io::uo) is det <= stream.writer(Stream, string, io).
-output_pseudo_op_float_args(OpName, FloatArgs, !IO) :-
- io.write_string("\t" ++ OpName ++ "\t", !IO),
- pseudo_op_float_args_while(FloatArgs, !IO),
- io.write_string("\n", !IO).
+output_pseudo_op_float_args(Stream, OpName, FloatArgs, !IO) :-
+ put(Stream, "\t" ++ OpName ++ "\t", !IO),
+ pseudo_op_float_args_while(Stream, FloatArgs, !IO),
+ put(Stream, "\n", !IO).
-:- pred pseudo_op_float_args_while(list(float)::in, io::di, io::uo) is det.
+:- pred pseudo_op_float_args_while(Stream::in, list(float)::in,
+ io::di, io::uo) is det <= stream.writer(Stream, string, io).
-pseudo_op_float_args_while([], !IO).
-pseudo_op_float_args_while([Arg | Args], !IO) :-
- io.write_float(Arg, !IO),
+pseudo_op_float_args_while(_, [], !IO).
+pseudo_op_float_args_while(Stream, [Arg | Args], !IO) :-
+ put_float(Stream, Arg, !IO),
(
Args = [],
- pseudo_op_float_args_while(Args, !IO)
+ pseudo_op_float_args_while(Stream, Args, !IO)
;
- Args = [_|_],
- io.write_string(",", !IO),
- pseudo_op_float_args_while(Args, !IO)
+ Args = [_ | _],
+ put(Stream, ",", !IO),
+ pseudo_op_float_args_while(Stream, Args, !IO)
).
- % Output pseudo-op having list of string as its argument.
+ % Output a pseudo-op that has a list of string as it's
+ % argument.
%
-:- pred output_pseudo_op_str_args(string::in, list(string)::in,
- io::di, io::uo) is det.
+:- pred output_pseudo_op_str_args(Stream::in, string::in, list(string)::in,
+ io::di, io::uo) is det <= stream.writer(Stream, string, io).
-output_pseudo_op_str_args(OpName, StrArgs, !IO) :-
- io.write_string("\t" ++ OpName ++ "\t", !IO),
- pseudo_op_str_args_while(StrArgs, !IO),
- io.write_string("\n", !IO).
+output_pseudo_op_str_args(Stream, OpName, StrArgs, !IO) :-
+ put(Stream, "\t" ++ OpName ++ "\t", !IO),
+ pseudo_op_str_args_while(Stream, StrArgs, !IO),
+ put(Stream, "\n", !IO).
-:- pred pseudo_op_str_args_while(list(string)::in, io::di, io::uo) is det.
+:- pred pseudo_op_str_args_while(Stream::in, list(string)::in,
+ io::di, io::uo) is det <= stream.writer(Stream, string, io).
-pseudo_op_str_args_while([], !IO).
-pseudo_op_str_args_while([Arg | Args], !IO) :-
- io.write_string(string.word_wrap("\"" ++ Arg ++ "\"", comment_length), !IO),
+pseudo_op_str_args_while(_, [], !IO).
+pseudo_op_str_args_while(Stream, [Arg | Args], !IO) :-
+ put(Stream, string.word_wrap("\"" ++ Arg ++ "\"", comment_length), !IO),
(
Args = [],
- pseudo_op_str_args_while(Args, !IO)
+ pseudo_op_str_args_while(Stream, Args, !IO)
;
- Args = [_|_],
- io.write_string(",", !IO),
- pseudo_op_str_args_while(Args, !IO)
+ Args = [_ | _],
+ put(Stream, ",", !IO),
+ pseudo_op_str_args_while(Stream, Args, !IO)
).
- % Check if FLAGS and TYPE argument of '.section' pseudo-op is valid
+ % Check if the FLAGS and TYPE argumentis of '.section' pseudo-op
+ % are valid.
%
:- pred check_section_flags_and_type(string::in, maybe(string)::in,
bool::out) is det.
@@ -403,7 +421,7 @@
Result = no
).
- % Check FLAGS argument of '.section' pseudo-op
+ % Check if the FLAGS argument of '.section' pseudo-op is valid.
%
:- pred check_pseudo_section_flags(list(char)::in, bool::out) is det.
@@ -451,61 +469,66 @@
%-----------------------------------------------------------------------------%
%
-% Output x86_64 instructions.
+% Output x86_64 instructions
%
% Output x86_64 instruction and x86_64_comment.
- %
-output_x86_64_instruction(x86_64_instr(Instr, Comment), !IO) :-
- output_x86_64_comment(Comment, !IO),
- output_x86_64_instr_list(Instr, !IO),
- io.write_string("\n", !IO).
+ %
+ % XXX There should be a way of turning of comments since we don't
+ % really want to output them in __asm__ blocks.
+ %
+output_x86_64_instruction(Stream, x86_64_instr(Instr, Comment), !IO) :-
+ output_x86_64_comment(Stream, Comment, !IO),
+ output_x86_64_instr_list(Stream, Instr, !IO),
+ put(Stream, "\n", !IO).
-:- pred output_x86_64_instr_list(list(x86_64_instr)::in, io::di, io::uo) is det.
+:- pred output_x86_64_instr_list(Stream::in, list(x86_64_instr)::in,
+ io::di, io::uo) is det <= stream.writer(Stream, string, io).
-output_x86_64_instr_list(Instrs, !IO) :-
- list.foldl(output_x86_64_instr, Instrs, !IO).
+output_x86_64_instr_list(Stream, Instrs, !IO) :-
+ list.foldl(output_x86_64_instr(Stream), Instrs, !IO).
-:- pred output_x86_64_instr(x86_64_instr::in, io::di, io::uo) is det.
+:- pred output_x86_64_instr(Stream::in, x86_64_instr::in,
+ io::di, io::uo) is det <= stream.writer(Stream, string, io).
-output_x86_64_instr(x86_64_comment(Comment), !IO) :-
+output_x86_64_instr(Stream, x86_64_comment(Comment), !IO) :-
( string.length(Comment) > 0 ->
- io.write_string("\t# ", !IO),
+ put(Stream, "\t# ", !IO),
( string.length(Comment) > comment_length ->
string.split(Comment, comment_length, Comment1, Comment2),
- io.write_string(string.word_wrap(Comment1, comment_length), !IO),
- io.write_string("\n", !IO),
- output_x86_64_instr(x86_64_comment(Comment2), !IO)
+ put(Stream, string.word_wrap(Comment1, comment_length), !IO),
+ put(Stream, "\n", !IO),
+ output_x86_64_instr(Stream, x86_64_comment(Comment2), !IO)
;
- io.write_string(string.word_wrap(Comment, comment_length), !IO)
+ put(Stream, string.word_wrap(Comment, comment_length), !IO)
)
;
true
).
-output_x86_64_instr(x86_64_label(LabelName), !IO) :-
+output_x86_64_instr(Stream, x86_64_label(LabelName), !IO) :-
( string.length(LabelName) > 0 ->
- io.write_string("\n" ++ LabelName ++ ":", !IO)
+ put(Stream, "\n" ++ LabelName ++ ":", !IO)
;
true
).
-output_x86_64_instr(x86_64_directive(PseudoOp), !IO) :-
- output_x86_64_pseudo_op(PseudoOp, !IO).
-output_x86_64_instr(x86_64_instr(Instr), !IO) :-
- output_x86_64_inst(Instr, !IO),
- io.write_string("\n", !IO).
-
+output_x86_64_instr(Stream, x86_64_directive(PseudoOp), !IO) :-
+ output_x86_64_pseudo_op(Stream, PseudoOp, !IO).
+output_x86_64_instr(Stream, x86_64_instr(Instr), !IO) :-
+ output_x86_64_inst(Stream, Instr, !IO),
+ put(Stream, "\n", !IO).
% Output a single x86_64 instruction and its operands (if any).
%
-:- pred output_x86_64_inst(x86_64_inst::in, io::di, io::uo) is det.
+:- pred output_x86_64_inst(Stream::in, x86_64_inst::in, io::di, io::uo)
+ is det <= stream.writer(Stream, string, io).
-output_x86_64_inst(adc(Src, Dest), !IO) :-
- output_instr_not_imm_dest("adc", Src, yes(Dest), !IO).
-output_x86_64_inst(add(Src, Dest), !IO) :-
- output_instr_not_imm_dest("add", Src, yes(Dest), !IO).
-output_x86_64_inst(and(Src, Dest), !IO) :-
- output_instr_not_imm_dest("and", Src, yes(Dest), !IO).
-output_x86_64_inst(bs(Src, Dest, Cond), !IO) :-
+output_x86_64_inst(Stream, adc(Src, Dest), !IO) :-
+ output_instr_not_imm_dest(Stream, "adc", Src, yes(Dest), !IO).
+output_x86_64_inst(Stream, add(Src, Dest), !IO) :-
+ output_instr_not_imm_dest(Stream, "add", Src, yes(Dest), !IO).
+output_x86_64_inst(Stream, and(Src, Dest), !IO) :-
+ output_instr_not_imm_dest(Stream, "and", Src, yes(Dest), !IO).
+output_x86_64_inst(Stream, bs(Src, Dest, Cond), !IO) :-
check_operand_not_immediate(Src, Result1),
(
Result1 = yes,
@@ -522,9 +545,9 @@
unexpected(this_file, "output_x86_64_inst: bs: unexpected:"
++ " invalid condition third operand")
),
- io.write_string("\t" ++ Instr ++ "\t", !IO),
+ put(Stream, "\t" ++ Instr ++ "\t", !IO),
operand_type(Dest, DestType),
- io.write_string(SrcType ++ ", " ++ DestType ++ "\t", !IO)
+ put(Stream, SrcType ++ ", " ++ DestType ++ "\t", !IO)
;
DestRes = no,
unexpected(this_file, "output_x86_64_instr: bs: unexpected:"
@@ -535,59 +558,59 @@
unexpected(this_file, "output_x86_64_instr: bsf: unexpected: first"
++ " operand is an immediate value")
).
-output_x86_64_inst(bswap(Op), !IO) :-
+output_x86_64_inst(Stream, bswap(Op), !IO) :-
check_operand_register(Op, Result),
(
Result = yes,
operand_type(Op, RegType),
- io.write_string("\tbswap\t" ++ RegType ++ "\t\t", !IO)
+ put(Stream, "\tbswap\t" ++ RegType ++ "\t\t", !IO)
;
Result = no,
unexpected(this_file, "output_x86_64_instr: bswap: unexpected: operand"
++ " is not a register")
).
-output_x86_64_inst(bt(Src, Idx), !IO) :-
- output_bit_test_instr("bt", Src, Idx, !IO).
-output_x86_64_inst(btc(Src, Idx), !IO) :-
- output_bit_test_instr("btc", Src, Idx, !IO).
-output_x86_64_inst(btr(Src, Idx), !IO) :-
- output_bit_test_instr("btr", Src, Idx, !IO).
-output_x86_64_inst(bts(Src, Idx), !IO) :-
- output_bit_test_instr("bts", Src, Idx, !IO).
-output_x86_64_inst(call(Target), !IO) :-
+output_x86_64_inst(Stream, bt(Src, Idx), !IO) :-
+ output_bit_test_instr(Stream, "bt", Src, Idx, !IO).
+output_x86_64_inst(Stream, btc(Src, Idx), !IO) :-
+ output_bit_test_instr(Stream, "btc", Src, Idx, !IO).
+output_x86_64_inst(Stream, btr(Src, Idx), !IO) :-
+ output_bit_test_instr(Stream, "btr", Src, Idx, !IO).
+output_x86_64_inst(Stream, bts(Src, Idx), !IO) :-
+ output_bit_test_instr(Stream, "bts", Src, Idx, !IO).
+output_x86_64_inst(Stream, call(Target), !IO) :-
check_operand_not_immediate(Target, Result),
(
Result = yes,
operand_type(Target, TargetType),
- io.write_string("\tcall\t" ++ TargetType ++ "\t\t", !IO)
+ put(Stream, "\tcall\t" ++ TargetType ++ "\t\t", !IO)
;
Result = no,
unexpected(this_file, "output_x86_64_instr: call: unexpected:"
++ " invalid target operand")
).
-output_x86_64_inst(cbw, !IO) :-
- io.write_string("\tcbw\t", !IO).
-output_x86_64_inst(cwde, !IO) :-
- io.write_string("\tcwde\t", !IO).
-output_x86_64_inst(cdqe, !IO) :-
- io.write_string("\tcdqe\t", !IO).
-output_x86_64_inst(cwd, !IO) :-
- io.write_string("\tcwd\t", !IO).
-output_x86_64_inst(cdq, !IO) :-
- io.write_string("\tcdq\t", !IO).
-output_x86_64_inst(cqo, !IO) :-
- io.write_string("\tcqo\t", !IO).
-output_x86_64_inst(clc, !IO) :-
- io.write_string("\tclc\t", !IO).
-output_x86_64_inst(cld, !IO) :-
- io.write_string("\tcld\t", !IO).
-output_x86_64_inst(cmc, !IO) :-
- io.write_string("\tcmc\t", !IO).
-output_x86_64_inst(cmov(Src, Dest, Cond), !IO) :-
- output_instr_with_condition("cmov", Src, yes(Dest), Cond, !IO).
-output_x86_64_inst(cmp(Src, Dest), !IO) :-
- output_instr_not_imm_dest("cmp", Src, yes(Dest), !IO).
-output_x86_64_inst(cmpxchg(Src, Dest), !IO) :-
+output_x86_64_inst(Stream, cbw, !IO) :-
+ put(Stream, "\tcbw\t", !IO).
+output_x86_64_inst(Stream, cwde, !IO) :-
+ put(Stream, "\tcwde\t", !IO).
+output_x86_64_inst(Stream, cdqe, !IO) :-
+ put(Stream, "\tcdqe\t", !IO).
+output_x86_64_inst(Stream, cwd, !IO) :-
+ put(Stream, "\tcwd\t", !IO).
+output_x86_64_inst(Stream, cdq, !IO) :-
+ put(Stream, "\tcdq\t", !IO).
+output_x86_64_inst(Stream, cqo, !IO) :-
+ put(Stream, "\tcqo\t", !IO).
+output_x86_64_inst(Stream, clc, !IO) :-
+ put(Stream, "\tclc\t", !IO).
+output_x86_64_inst(Stream, cld, !IO) :-
+ put(Stream, "\tcld\t", !IO).
+output_x86_64_inst(Stream, cmc, !IO) :-
+ put(Stream, "\tcmc\t", !IO).
+output_x86_64_inst(Stream, cmov(Src, Dest, Cond), !IO) :-
+ output_instr_with_condition(Stream, "cmov", Src, yes(Dest), Cond, !IO).
+output_x86_64_inst(Stream, cmp(Src, Dest), !IO) :-
+ output_instr_not_imm_dest(Stream, "cmp", Src, yes(Dest), !IO).
+output_x86_64_inst(Stream, cmpxchg(Src, Dest), !IO) :-
check_operand_not_immediate(Src, Result1),
(
Result1 = yes,
@@ -596,7 +619,7 @@
Result2 = yes,
operand_type(Src, Op1),
operand_type(Dest, Op2),
- io.write_string("\tcmp\t" ++ Op1 ++ ", " ++ Op2 ++ "\t", !IO)
+ put(Stream, "\tcmp\t" ++ Op1 ++ ", " ++ Op2 ++ "\t", !IO)
;
Result2 = no,
unexpected(this_file, "output_x86_64_instr: xmpxchg: unexpected:"
@@ -607,22 +630,22 @@
unexpected(this_file, "output_x86_64_instr: xmpxchg: unexpected:"
++ " invalid first operand")
).
-output_x86_64_inst(cmpxchg8b(Op), !IO) :-
+output_x86_64_inst(Stream, cmpxchg8b(Op), !IO) :-
check_operand_not_mem_ref(Op, Result),
(
Result = no,
operand_type(Op, OpType),
- io.write_string("\tcmpxchg8b" ++ OpType, !IO)
+ put(Stream, "\tcmpxchg8b" ++ OpType, !IO)
;
Result = yes,
unexpected(this_file, "output_x86_64_instr: cmpxchg8b: unexpected:"
++ "invalid operand")
).
-output_x86_64_inst(dec(Operand), !IO) :-
- output_instr_not_imm_dest("dec", Operand, no, !IO).
-output_x86_64_inst(div(Operand), !IO) :-
- output_instr_not_imm_dest("div", Operand, no, !IO).
-output_x86_64_inst(enter(StackSize, NestingLevel), !IO) :-
+output_x86_64_inst(Stream, dec(Operand), !IO) :-
+ output_instr_not_imm_dest(Stream, "dec", Operand, no, !IO).
+output_x86_64_inst(Stream, div(Operand), !IO) :-
+ output_instr_not_imm_dest(Stream, "div", Operand, no, !IO).
+output_x86_64_inst(Stream, enter(StackSize, NestingLevel), !IO) :-
StackSize = uint16(Size),
NestingLevel = uint8(Level),
check_unsigned_int_size(16, Size, Result0),
@@ -631,20 +654,20 @@
Result0 = yes,
Result1 = yes
->
- io.write_string("\tenter\t", !IO),
- io.write_int(Size, !IO),
- io.write_string(",", !IO),
- io.write_int(Level, !IO),
- io.write_string("\t", !IO)
+ put(Stream, "\tenter\t", !IO),
+ put_int(Stream, Size, !IO),
+ put(Stream, ",", !IO),
+ put_int(Stream, Level, !IO),
+ put(Stream, "\t", !IO)
;
unexpected(this_file, "output_x86_64_instr: enter: unexpected:"
++ " check_unsigned_int_size failed")
).
-output_x86_64_inst(idiv(Operand), !IO) :-
- output_instr_not_imm_dest("idiv", Operand, no, !IO).
-output_x86_64_inst(imul(Src, Dest, Mult), !IO) :-
+output_x86_64_inst(Stream, idiv(Operand), !IO) :-
+ output_instr_not_imm_dest(Stream, "idiv", Operand, no, !IO).
+output_x86_64_inst(Stream, imul(Src, Dest, Mult), !IO) :-
operand_type(Src, SrcType),
- io.write_string("\timul\t" ++ SrcType, !IO),
+ put(Stream, "\timul\t" ++ SrcType, !IO),
(
Dest = yes(DestRes),
check_operand_register(DestRes, Result1),
@@ -656,29 +679,29 @@
TempReg = operand_reg(gp_reg(13)),
operand_type(TempReg, DestType)
),
- io.write_string(", " ++ DestType, !IO),
+ put(Stream, ", " ++ DestType, !IO),
(
Mult = yes(MultRes),
operand_type(MultRes, Op3),
- io.write_string(", " ++ Op3 ++ " ", !IO)
+ put(Stream, ", " ++ Op3 ++ " ", !IO)
;
Mult = no,
- io.write_string("\t", !IO)
+ put(Stream, "\t", !IO)
)
;
Dest = no,
- io.write_string("\t\t", !IO)
+ put(Stream, "\t\t", !IO)
).
-output_x86_64_inst(inc(Operand), !IO) :-
- output_instr_not_imm_dest("inc", Operand, no, !IO).
-output_x86_64_inst(j(Offset, Cond), !IO) :-
- output_instr_with_condition("j", Offset, no, Cond, !IO).
-output_x86_64_inst(jrcxz(RelOffset), !IO) :-
- output_instr_8bit_rel_offset("jrcxz", RelOffset, !IO).
-output_x86_64_inst(jmp(Target), !IO) :-
+output_x86_64_inst(Stream, inc(Operand), !IO) :-
+ output_instr_not_imm_dest(Stream, "inc", Operand, no, !IO).
+output_x86_64_inst(Stream, j(Offset, Cond), !IO) :-
+ output_instr_with_condition(Stream, "j", Offset, no, Cond, !IO).
+output_x86_64_inst(Stream, jrcxz(RelOffset), !IO) :-
+ output_instr_8bit_rel_offset(Stream, "jrcxz", RelOffset, !IO).
+output_x86_64_inst(Stream, jmp(Target), !IO) :-
operand_type(Target, Op),
- io.write_string("\tjmp\t" ++ Op ++ "\t\t", !IO).
-output_x86_64_inst(lea(Src, Dest), !IO) :-
+ put(Stream, "\tjmp\t" ++ Op ++ "\t\t", !IO).
+output_x86_64_inst(Stream, lea(Src, Dest), !IO) :-
check_operand_not_mem_ref(Src, Result1),
(
Result1 = no,
@@ -687,7 +710,7 @@
Result2 = yes,
operand_type(Src, Op1),
operand_type(Dest, Op2),
- io.write_string("\tlea\t" ++ Op1 ++ ", " ++ Op2 ++ "\t", !IO)
+ put(Stream, "\tlea\t" ++ Op1 ++ ", " ++ Op2 ++ "\t", !IO)
;
Result2 = no,
unexpected(this_file, "output_x86_64_inst: lea: unexpected:"
@@ -698,41 +721,41 @@
unexpected(this_file, "output_x86_64_inst: lea: unexpected:"
++ " invalid first operand")
).
-output_x86_64_inst(leave, !IO) :-
- io.write_string("\tleave\t", !IO).
-output_x86_64_inst(loop(RelOffset), !IO) :-
- output_instr_8bit_rel_offset("loop", RelOffset, !IO).
-output_x86_64_inst(loope(RelOffset), !IO) :-
- output_instr_8bit_rel_offset("loope", RelOffset, !IO).
-output_x86_64_inst(loopne(RelOffset), !IO) :-
- output_instr_8bit_rel_offset("loopne", RelOffset, !IO).
-output_x86_64_inst(loopnz(RelOffset), !IO) :-
- output_instr_8bit_rel_offset("loopnz", RelOffset, !IO).
-output_x86_64_inst(loopz(RelOffset), !IO) :-
- output_instr_8bit_rel_offset("loopz", RelOffset, !IO).
-output_x86_64_inst(mov(Src, Dest), !IO) :-
- output_instr_not_imm_dest("mov", Src, yes(Dest), !IO).
-output_x86_64_inst(mul(Operand), !IO) :-
- output_instr_not_imm_dest("mul", Operand, no, !IO).
-output_x86_64_inst(neg(Operand), !IO) :-
- output_instr_not_imm_dest("neg", Operand, no, !IO).
-output_x86_64_inst(nop, !IO) :-
- io.write_string("nop", !IO).
-output_x86_64_inst(x86_64_instr_not(Operand), !IO) :-
- output_instr_not_imm_dest("not", Operand, no, !IO).
-output_x86_64_inst(or(Src, Dest), !IO) :-
- output_instr_not_imm_dest("or", Src, yes(Dest), !IO).
-output_x86_64_inst(pop(Operand), !IO) :-
- output_instr_not_imm_dest("pop", Operand, no, !IO).
-output_x86_64_inst(popfq, !IO) :-
- io.write_string("\tpopfq\t", !IO).
-output_x86_64_inst(push(Operand), !IO) :-
- io.write_string("\tpush\t", !IO),
+output_x86_64_inst(Stream, leave, !IO) :-
+ put(Stream, "\tleave\t", !IO).
+output_x86_64_inst(Stream, loop(RelOffset), !IO) :-
+ output_instr_8bit_rel_offset(Stream, "loop", RelOffset, !IO).
+output_x86_64_inst(Stream, loope(RelOffset), !IO) :-
+ output_instr_8bit_rel_offset(Stream, "loope", RelOffset, !IO).
+output_x86_64_inst(Stream, loopne(RelOffset), !IO) :-
+ output_instr_8bit_rel_offset(Stream, "loopne", RelOffset, !IO).
+output_x86_64_inst(Stream, loopnz(RelOffset), !IO) :-
+ output_instr_8bit_rel_offset(Stream, "loopnz", RelOffset, !IO).
+output_x86_64_inst(Stream, loopz(RelOffset), !IO) :-
+ output_instr_8bit_rel_offset(Stream, "loopz", RelOffset, !IO).
+output_x86_64_inst(Stream, mov(Src, Dest), !IO) :-
+ output_instr_not_imm_dest(Stream, "mov", Src, yes(Dest), !IO).
+output_x86_64_inst(Stream, mul(Operand), !IO) :-
+ output_instr_not_imm_dest(Stream, "mul", Operand, no, !IO).
+output_x86_64_inst(Stream, neg(Operand), !IO) :-
+ output_instr_not_imm_dest(Stream, "neg", Operand, no, !IO).
+output_x86_64_inst(Stream, nop, !IO) :-
+ put(Stream, "nop", !IO).
+output_x86_64_inst(Stream, x86_64_instr_not(Operand), !IO) :-
+ output_instr_not_imm_dest(Stream, "not", Operand, no, !IO).
+output_x86_64_inst(Stream, or(Src, Dest), !IO) :-
+ output_instr_not_imm_dest(Stream, "or", Src, yes(Dest), !IO).
+output_x86_64_inst(Stream, pop(Operand), !IO) :-
+ output_instr_not_imm_dest(Stream, "pop", Operand, no, !IO).
+output_x86_64_inst(Stream, popfq, !IO) :-
+ put(Stream, "\tpopfq\t", !IO).
+output_x86_64_inst(Stream, push(Operand), !IO) :-
+ put(Stream, "\tpush\t", !IO),
operand_type(Operand, OperandType),
- io.write_string(OperandType ++ "\t", !IO).
-output_x86_64_inst(pushfq, !IO) :-
- io.write_string("\tpushfq\t", !IO).
-output_x86_64_inst(rc(Amnt, Dest, Cond), !IO) :-
+ put(Stream, OperandType ++ "\t", !IO).
+output_x86_64_inst(Stream, pushfq, !IO) :-
+ put(Stream, "\tpushfq\t", !IO).
+output_x86_64_inst(Stream, rc(Amnt, Dest, Cond), !IO) :-
check_rc_first_operand(Amnt, Result1),
(
Result1 = yes,
@@ -741,8 +764,8 @@
Result2 = yes,
operand_type(Amnt, Op1),
operand_type(Dest, Op2),
- io.write_string("\trc\t" ++ Cond, !IO),
- io.write_string(Op1 ++ ", " ++ Op2 ++ "\t", !IO)
+ put(Stream, "\trc\t" ++ Cond, !IO),
+ put(Stream, Op1 ++ ", " ++ Op2 ++ "\t", !IO)
;
Result2 = no,
unexpected(this_file, "output_x86_64_instr: rc: unexpected"
@@ -753,7 +776,7 @@
unexpected(this_file, "output_x86_64_instr: rc: unexpected"
++ " invalid first operand")
).
-output_x86_64_inst(ret(Op), !IO) :-
+output_x86_64_inst(Stream, ret(Op), !IO) :-
(
Op = yes(OpRes),
OpRes = uint16(NumBytes)
@@ -761,9 +784,9 @@
check_unsigned_int_size(16, NumBytes, Result),
(
Result = yes,
- io.write_string("\tret\t", !IO),
- io.write_int(NumBytes, !IO),
- io.write_string("\t", !IO)
+ put(Stream, "\tret\t", !IO),
+ put_int(Stream, NumBytes, !IO),
+ put(Stream, "\t", !IO)
;
Result = no,
unexpected(this_file, "output_x86_64_instr: ret: unexpected:"
@@ -772,12 +795,12 @@
;
Op = no
->
- io.write_string("\tret\t\t", !IO)
+ put(Stream, "\tret\t\t", !IO)
;
unexpected(this_file, "output_x86_64_instr: ret: unexpected"
++ " invalid operand")
).
-output_x86_64_inst(ro(Amnt, Dest, Dir), !IO) :-
+output_x86_64_inst(Stream, ro(Amnt, Dest, Dir), !IO) :-
check_operand_not_mem_ref(Amnt, Result1),
(
Result1 = yes,
@@ -786,8 +809,8 @@
Result2 = yes,
operand_type(Amnt, Op1),
operand_type(Dest, Op2),
- io.write_string("\tro" ++ Dir ++ "\t", !IO),
- io.write_string(Op1 ++ ", " ++ Op2 ++ "\t\t", !IO)
+ put(Stream, "\tro" ++ Dir ++ "\t", !IO),
+ put(Stream, Op1 ++ ", " ++ Op2 ++ "\t\t", !IO)
;
Result2 = no,
unexpected(this_file, "output_x86_64_instr: ro: unexpected:"
@@ -798,7 +821,7 @@
unexpected(this_file, "output_x86_64_instr: ro: unexpected"
++ " invalid first operand")
).
-output_x86_64_inst(sal(Amnt, Dest), !IO) :-
+output_x86_64_inst(Stream, sal(Amnt, Dest), !IO) :-
check_operand_unsigned_imm_or_reg(Amnt, Result1),
(
Result1 = yes,
@@ -807,7 +830,7 @@
Result2 = yes,
operand_type(Amnt, Op1),
operand_type(Dest, Op2),
- io.write_string("\tsal\t" ++ Op1 ++ ", " ++ Op2 ++ "\t", !IO)
+ put(Stream, "\tsal\t" ++ Op1 ++ ", " ++ Op2 ++ "\t", !IO)
;
Result2 = no,
unexpected(this_file, "output_x86_64_instr: sal: unexpected:"
@@ -818,7 +841,7 @@
unexpected(this_file, "output_x86_64_instr: sal: unexpected:"
++ "invalid first operand")
).
-output_x86_64_inst(shl(Amnt, Dest), !IO) :-
+output_x86_64_inst(Stream, shl(Amnt, Dest), !IO) :-
check_operand_unsigned_imm_or_reg(Amnt, Result1),
(
Result1 = yes,
@@ -827,7 +850,7 @@
Result2 = yes,
operand_type(Amnt, Op1),
operand_type(Dest, Op2),
- io.write_string("\tshl\t" ++ Op1 ++ ", " ++ Op2 ++ "\t", !IO)
+ put(Stream, "\tshl\t" ++ Op1 ++ ", " ++ Op2 ++ "\t", !IO)
;
Result2 = no,
unexpected(this_file, "output_x86_64_instr: shl: unexpected:"
@@ -838,7 +861,7 @@
unexpected(this_file, "output_x86_64_instr: shl: unexpected:"
++ " invalid first operand")
).
-output_x86_64_inst(sar(Amnt, Dest), !IO) :-
+output_x86_64_inst(Stream, sar(Amnt, Dest), !IO) :-
check_operand_unsigned_imm_or_reg(Amnt, Result1),
(
Result1 = yes,
@@ -847,7 +870,7 @@
Result2 = yes,
operand_type(Amnt, Op1),
operand_type(Dest, Op2),
- io.write_string("\tsar\t" ++ Op1 ++ ", " ++ Op2 ++ "\t", !IO)
+ put(Stream, "\tsar\t" ++ Op1 ++ ", " ++ Op2 ++ "\t", !IO)
;
Result2 = no,
unexpected(this_file, "output_x86_64_instr: sar: unexpected:"
@@ -858,19 +881,19 @@
unexpected(this_file, "output_x86_64_instr: sar: unexpected:"
++ " invalid first operand")
).
-output_x86_64_inst(sbb(Src, Dest), !IO) :-
- output_instr_not_imm_dest("sbb", Src, yes(Dest), !IO).
-output_x86_64_inst(set(Operand, Cond), !IO) :-
+output_x86_64_inst(Stream, sbb(Src, Dest), !IO) :-
+ output_instr_not_imm_dest(Stream, "sbb", Src, yes(Dest), !IO).
+output_x86_64_inst(Stream, set(Operand, Cond), !IO) :-
check_operand_not_immediate(Operand, Result),
(
Result = yes,
- output_instr_with_condition("set", Operand, no, Cond, !IO)
+ output_instr_with_condition(Stream, "set", Operand, no, Cond, !IO)
;
Result = no,
unexpected(this_file, "output_x86_64_instr: set: unexpected"
++ " invalid first operand")
).
-output_x86_64_inst(shld(Amnt, Dest1, Reg), !IO) :-
+output_x86_64_inst(Stream, shld(Amnt, Dest1, Reg), !IO) :-
check_operand_unsigned_imm_or_reg(Amnt, Result1),
(
Result1 = yes,
@@ -883,8 +906,8 @@
operand_type(Amnt, Op1),
operand_type(Amnt, Op2),
operand_type(Amnt, Op3),
- io.write_string("\tshld\t" ++ Op1 ++ ", ", !IO),
- io.write_string(Op2 ++ ", " ++ Op3 ++ "\t", !IO)
+ put(Stream, "\tshld\t" ++ Op1 ++ ", ", !IO),
+ put(Stream, Op2 ++ ", " ++ Op3 ++ "\t", !IO)
;
Result3 = no,
unexpected(this_file, "output_x86_64_instr: shld: unexpected:"
@@ -900,7 +923,7 @@
unexpected(this_file, "output_x86_64_instr: shld: unexpected"
++ " invalid first operand")
).
-output_x86_64_inst(shr(Amnt, Dest), !IO) :-
+output_x86_64_inst(Stream, shr(Amnt, Dest), !IO) :-
check_operand_unsigned_imm_or_reg(Amnt, Result1),
(
Result1 = yes,
@@ -909,7 +932,7 @@
Result2 = yes,
operand_type(Amnt, Op1),
operand_type(Dest, Op2),
- io.write_string("\tshr\t" ++ Op1 ++ ", " ++ Op2 ++ "\t", !IO)
+ put(Stream, "\tshr\t" ++ Op1 ++ ", " ++ Op2 ++ "\t", !IO)
;
Result2 = no,
unexpected(this_file, "output_x86_64_instr: shr: unexpected"
@@ -920,7 +943,7 @@
unexpected(this_file, "output_x86_64_instr: shr: unexpected"
++ " invalid first operand")
).
-output_x86_64_inst(shrd(Amnt, Dest1, Reg), !IO) :-
+output_x86_64_inst(Stream, shrd(Amnt, Dest1, Reg), !IO) :-
check_operand_unsigned_imm_or_reg(Amnt, Result1),
(
Result1 = yes,
@@ -933,8 +956,8 @@
operand_type(Amnt, Op1),
operand_type(Amnt, Op2),
operand_type(Amnt, Op3),
- io.write_string("\tshrd\t" ++ Op1 ++ ", ", !IO),
- io.write_string(Op2 ++ ", " ++ Op3 ++ "\t", !IO)
+ put(Stream, "\tshrd\t" ++ Op1 ++ ", ", !IO),
+ put(Stream, Op2 ++ ", " ++ Op3 ++ "\t", !IO)
;
Result3 = no,
unexpected(this_file, "output_x86_64_instr: shrd: unexpected"
@@ -950,13 +973,13 @@
unexpected(this_file, "output_x86_64_instr: shrd: unexpected:"
++ " invalid first operand")
).
-output_x86_64_inst(stc, !IO) :-
- io.write_string("\tstc\t", !IO).
-output_x86_64_inst(std, !IO) :-
- io.write_string("\tstd\t", !IO).
-output_x86_64_inst(sub(Src, Dest), !IO) :-
- output_instr_not_imm_dest("sub", Src, yes(Dest), !IO).
-output_x86_64_inst(test(Src1, Src2), !IO) :-
+output_x86_64_inst(Stream, stc, !IO) :-
+ put(Stream, "\tstc\t", !IO).
+output_x86_64_inst(Stream, std, !IO) :-
+ put(Stream, "\tstd\t", !IO).
+output_x86_64_inst(Stream, sub(Src, Dest), !IO) :-
+ output_instr_not_imm_dest(Stream, "sub", Src, yes(Dest), !IO).
+output_x86_64_inst(Stream, test(Src1, Src2), !IO) :-
check_operand_not_mem_ref(Src1, Result1),
(
Result1 = yes,
@@ -965,7 +988,7 @@
Result2 = yes,
operand_type(Src1, Op1),
operand_type(Src2, Op2),
- io.write_string("\ttest\t" ++ Op1 ++ ", " ++ Op2 ++ "\t", !IO)
+ put(Stream, "\ttest\t" ++ Op1 ++ ", " ++ Op2 ++ "\t", !IO)
;
Result2 = no,
unexpected(this_file, "output_x86_64_instr: test: unexpected"
@@ -976,7 +999,7 @@
unexpected(this_file, "output_x86_64_instr: test: unexpected"
++ " invalid first operand")
).
-output_x86_64_inst(xadd(Src, Dest), !IO) :-
+output_x86_64_inst(Stream, xadd(Src, Dest), !IO) :-
check_operand_register(Src, Result1),
(
Result1 = yes,
@@ -985,7 +1008,7 @@
Result2 = yes,
operand_type(Src, Op1),
operand_type(Dest, Op2),
- io.write_string("\txadd\t" ++ Op1 ++ ", " ++ Op2 ++ "\t", !IO)
+ put(Stream, "\txadd\t" ++ Op1 ++ ", " ++ Op2 ++ "\t", !IO)
;
Result2 = no,
unexpected(this_file, "output_x86_64_instr: unexpected
@@ -996,7 +1019,7 @@
unexpected(this_file, "output_x86_64_instr: unexpected
xadd first operand is not a register")
).
-output_x86_64_inst(xchg(Src1, Src2), !IO) :-
+output_x86_64_inst(Stream, xchg(Src1, Src2), !IO) :-
check_operand_reg_or_mem(Src1, Result1),
(
Result1 = yes,
@@ -1005,7 +1028,7 @@
Result2 = yes,
operand_type(Src1, Op1),
operand_type(Src2, Op2),
- io.write_string("\txchg\t" ++ Op1 ++ ", " ++ Op2 ++ "\t", !IO)
+ put(Stream, "\txchg\t" ++ Op1 ++ ", " ++ Op2 ++ "\t", !IO)
;
Result2 = no,
unexpected(this_file, "output_x86_64_instr: xchg: unexpected"
@@ -1016,24 +1039,25 @@
unexpected(this_file, "output_x86_64_instr: xchg: unexpected"
++ " invalid second operand")
).
-output_x86_64_inst(xor(Src, Dest), !IO) :-
- output_instr_not_imm_dest("xor", Src, yes(Dest), !IO).
+output_x86_64_inst(Stream, xor(Src, Dest), !IO) :-
+ output_instr_not_imm_dest(Stream, "xor", Src, yes(Dest), !IO).
-:- pred output_x86_64_comment(string::in, io::di, io::uo) is det.
+:- pred output_x86_64_comment(Stream::in, string::in, io::di, io::uo)
+ is det <= stream.writer(Stream, string, io).
-output_x86_64_comment(Comment, !IO) :-
+output_x86_64_comment(Stream, Comment, !IO) :-
( string.length(Comment) > 0 ->
- io.write_string("\t# ", !IO),
- io.write_string(Comment, !IO)
+ put(Stream, "\t# ", !IO),
+ put(Stream, Comment, !IO)
;
true
),
- io.write_string("\n", !IO).
+ put(Stream, "\n", !IO).
%-----------------------------------------------------------------------------%
%
-% Output of x86_64 operands.
+% Conversion x86_64 operands to strings
%
% Output a string representation of an immediate value.
@@ -1047,7 +1071,6 @@
imm_op_type(imm32(int32(Val)), ImmVal) :-
ImmVal = "$" ++ string.int_to_string(Val).
-
:- func reg_type(gp_reg) = string.
reg_type(gp_reg(RegNum)) = "%r" ++ string.int_to_string(RegNum).
@@ -1069,7 +1092,8 @@
( Offset = 0 ->
BaseAddress = "(" ++ reg_type(Reg) ++ ")"
;
- BaseAddress = string.int_to_string(Offset) ++ "(" ++ reg_type(Reg) ++ ")"
+ BaseAddress = string.int_to_string(Offset) ++
+ "(" ++ reg_type(Reg) ++ ")"
).
base_address_type(base_expr(Expr), DispType) :-
DispType = "$" ++ Expr.
@@ -1151,16 +1175,17 @@
%-----------------------------------------------------------------------------%
%
-% Subsection of "Output of x86_64 instructions".
+% Auxiliary predicates for outputting x86_64 instructions
%
- % Output an instruction with either one or two operand(s). If the second
- % operand is present, it cannot be an immediate operand.
+ % Output an instruction with either one or two operand(s).
+ % If the second operand is present, it must not be immediate operand.
%
-:- pred output_instr_not_imm_dest(string::in, operand::in, maybe(operand)::in,
- io::di, io::uo) is det.
+:- pred output_instr_not_imm_dest(Stream::in, string::in, operand::in,
+ maybe(operand)::in, io::di, io::uo)
+ is det <= stream.writer(Stream, string, io).
-output_instr_not_imm_dest(Instr, Op1, Op2, !IO) :-
+output_instr_not_imm_dest(Stream, Instr, Op1, Op2, !IO) :-
operand_type(Op1, Op1Type),
(
Op2 = yes(Op2Result),
@@ -1171,14 +1196,14 @@
check_operand_not_immediate(Op2Result, Result2),
(
Result2 = yes,
- io.write_string("\t" ++ Instr ++ "\t", !IO),
- io.write_string(Op1Type ++ ", " ++ Op2Type ++ "\t", !IO)
+ put(Stream, "\t" ++ Instr ++ "\t", !IO),
+ put(Stream, Op1Type ++ ", " ++ Op2Type ++ "\t", !IO)
;
Result2 = no,
- io.write_string("\tmov\t" ++ Op2Type ++ ", %r13\t", !IO),
- io.write_string("# move immediate to temp reg\n", !IO),
- io.write_string("\t" ++ Instr ++ "\t", !IO),
- io.write_string(Op1Type ++ ", " ++ "%r13\t", !IO)
+ put(Stream, "\tmov\t" ++ Op2Type ++ ", %r13\t", !IO),
+ put(Stream, "# move immediate to temp reg\n", !IO),
+ put(Stream, "\t" ++ Instr ++ "\t", !IO),
+ put(Stream, Op1Type ++ ", " ++ "%r13\t", !IO)
)
;
Result1 = no,
@@ -1187,18 +1212,16 @@
)
;
Op2 = no,
- io.write_string(Op1Type ++ "\t\t", !IO)
+ put(Stream, Op1Type ++ "\t\t", !IO)
).
- % Output an instruction with a signed offset relative to the instruction
- % pointer as an operand.
% Output an instruction with a signed 8-bit offset relative to the
% instruction pointer as an operand.
%
-:- pred output_instr_8bit_rel_offset(string::in, operand::in,
- io::di, io::uo) is det.
+:- pred output_instr_8bit_rel_offset(Stream::in, string::in, operand::in,
+ io::di, io::uo) is det <= stream.writer(Stream, string, io).
-output_instr_8bit_rel_offset(InstrName, RelOffset, !IO) :-
+output_instr_8bit_rel_offset(Stream, InstrName, RelOffset, !IO) :-
check_operand_rel_offset(RelOffset, Result1),
(
Result1 = yes,
@@ -1207,9 +1230,9 @@
check_signed_int_size(8, Val, Result2),
(
Result2 = yes,
- io.write_string("\t" ++ InstrName ++ "\t", !IO),
- io.write_int(Val, !IO),
- io.write_string("\t\t", !IO)
+ put(Stream, "\t" ++ InstrName ++ "\t", !IO),
+ put_int(Stream, Val, !IO),
+ put(Stream, "\t\t", !IO)
;
Result2 = no,
unexpected(this_file, "output_instr_8bit_rel_offset:"
@@ -1225,10 +1248,10 @@
++ " invalid operand - operand is not a relative offset")
).
-:- pred output_bit_test_instr(string::in, operand::in, operand::in, io::di,
- io::uo) is det.
+:- pred output_bit_test_instr(Stream::in, string::in, operand::in,
+ operand::in, io::di, io::uo) is det <= stream.writer(Stream, string, io).
-output_bit_test_instr(Instr, Src, Idx, !IO) :-
+output_bit_test_instr(Stream, Instr, Src, Idx, !IO) :-
check_operand_not_immediate(Src, Result1),
(
Result1 = yes,
@@ -1241,8 +1264,8 @@
check_signed_int_size(8, IdxInt, Result3),
(
Result3 = yes,
- io.write_string("\t" ++ Instr ++ "\t", !IO),
- io.write_string(Op1 ++ ", " ++ Op2 ++ "\t", !IO)
+ put(Stream, "\t" ++ Instr ++ "\t", !IO),
+ put(Stream, Op1 ++ ", " ++ Op2 ++ "\t", !IO)
;
Result3 = no,
unexpected(this_file, "output_bit_test_instr: bt:"
@@ -1263,25 +1286,26 @@
++ " invalid first operand - immediate value is not allowed")
).
-:- pred output_instr_with_condition(string::in, operand::in, maybe(operand)::in,
- condition::in, io::di, io::uo) is det.
+:- pred output_instr_with_condition(Stream::in, string::in, operand::in,
+ maybe(operand)::in, condition::in, io::di, io::uo)
+ is det <= stream.writer(Stream, string, io).
-output_instr_with_condition(Instr, Op1, Op2, Cond, !IO) :-
+output_instr_with_condition(Stream, Instr, Op1, Op2, Cond, !IO) :-
check_operand_not_immediate(Op1, Result1),
(
Result1 = yes,
instr_condition(Cond, CondRes),
- io.write_string("\t" ++ Instr, !IO),
- io.write_string(CondRes ++ "\t", !IO),
+ put(Stream, "\t" ++ Instr, !IO),
+ put(Stream, CondRes ++ "\t", !IO),
operand_type(Op1, Op1Type),
- io.write_string(Op1Type, !IO),
+ put(Stream, Op1Type, !IO),
(
Op2 = yes(Op2Res),
check_operand_register(Op2Res, Result3),
(
Result3 = yes,
operand_type(Op2Res, Op2Type),
- io.write_string(", " ++ Op2Type, !IO)
+ put(Stream, ", " ++ Op2Type, !IO)
;
Result3 = no,
unexpected(this_file, "output_instr_with_condition:"
@@ -1289,7 +1313,7 @@
)
;
Op2 = no,
- io.write_string("\t\t", !IO)
+ put(Stream, "\t\t", !IO)
)
;
Result1 = no,
@@ -1490,5 +1514,6 @@
this_file = "x86_64_out.m".
+%-----------------------------------------------------------------------------%
:- end_module x86_64_out.
%-----------------------------------------------------------------------------%
--------------------------------------------------------------------------
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