Files
mercury/compiler/builtin_ops.m
Fergus Henderson 7597790760 Use sub-modules to structure the modules in the Mercury compiler directory.
The main aim of this change is to make the overall, high-level structure
of the compiler clearer, and to encourage better encapsulation of the
major components.

compiler/libs.m:
compiler/backend_libs.m:
compiler/parse_tree.m:
compiler/hlds.m:
compiler/check_hlds.m:
compiler/transform_hlds.m:
compiler/bytecode_backend.m:
compiler/aditi_backend.m:
compiler/ml_backend.m:
compiler/ll_backend.m:
compiler/top_level.m:
	New files.  One module for each of the major components of the
	Mercury compiler.  These modules contain (as separate sub-modules)
	all the other modules in the Mercury compiler, except gcc.m and
	mlds_to_gcc.m.

Mmakefile:
compiler/Mmakefile:
	Handle the fact that the top-level module is now `top_level',
	not `mercury_compile' (since `mercury_compile' is a sub-module
	of `top_level').

compiler/Mmakefile:
	Update settings of *FLAGS-<modulename> to use the appropriate
	nested module names.

compiler/recompilation_check.m:
compiler/recompilation_version.m:
compiler/recompilation_usage.m:
compiler/recompilation.check.m:
compiler/recompilation.version.m:
compiler/recompilation.version.m:
	Convert the `recompilation_*' modules into sub-modules of the
	`recompilation' module.

compiler/*.m:
compiler/*.pp:
	Module-qualify the module names in `:- module', `:- import_module',
	and `:- use_module' declarations.

compiler/base_type_info.m:
compiler/base_type_layout.m:
	Deleted these unused empty modules.

compiler/prog_data.m:
compiler/globals.m:
	Move the `foreign_language' type from prog_data to globals.

compiler/mlds.m:
compiler/ml_util.m:
compiler/mlds_to_il.m:
	Import `globals', for `foreign_language'.

Mmake.common.in:
trace/Mmakefile:
runtime/Mmakefile:
	Rename the %.check.c targets as %.check_hdr.c,
	to avoid conflicts with compiler/recompilation.check.c.
2002-03-20 12:37:56 +00:00

246 lines
8.5 KiB
Mathematica

%-----------------------------------------------------------------------------%
% Copyright (C) 1999-2001 The University of Melbourne.
% This file may only be copied under the terms of the GNU General
% Public License - see the file COPYING in the Mercury distribution.
%-----------------------------------------------------------------------------%
% builtin_ops.m -- defines the builtin operator types.
% Main author: fjh.
%
% This module defines various types which enumerate the different builtin
% operators. Several of the different back-ends -- the bytecode back-end,
% the LLDS, and the MLDS -- all use the same set of builtin operators.
% These operators are defined here.
%-----------------------------------------------------------------------------%
:- module backend_libs__builtin_ops.
:- interface.
:- import_module parse_tree__prog_data, hlds__hlds_pred.
:- import_module list.
:- type unary_op
---> mktag
; tag
; unmktag
; strip_tag
; mkbody
; unmkbody
; hash_string
; bitwise_complement
; (not).
:- type binary_op
---> (+) % integer arithmetic
; (-)
; (*)
; (/) % integer division
% assumed to truncate toward zero
; (mod) % remainder (w.r.t. truncating integer division)
% XXX `mod' should be renamed `rem'
; (<<) % unchecked left shift
; (>>) % unchecked right shift
; (&) % bitwise and
; ('|') % bitwise or
; (^) % bitwise xor
; (and) % logical and
; (or) % logical or
; eq % ==
; ne % !=
; body
; array_index(array_elem_type)
; str_eq % string comparisons
; str_ne
; str_lt
; str_gt
; str_le
; str_ge
; (<) % signed integer comparions
; (>)
; (<=)
; (>=)
; unsigned_le % unsigned integer comparison
% Note that the arguments to `unsigned_le' are just ordinary
% (signed) Mercury ints, but it does the comparison as
% if they were first cast to an unsigned type, so e.g.
% binary(unsigned_le, int_const(1), int_const(-1) returns true,
% since (MR_Unsigned) 1 <= (MR_Unsigned) -1).
; float_plus
; float_minus
; float_times
; float_divide
; float_eq
; float_ne
; float_lt
; float_gt
; float_le
; float_ge.
% For the MLDS back-end, we need to know the element type for each
% array_index operation.
%
% Currently array index operations are only generated in limited
% circumstances. Using a simple representation for them here,
% rather than just putting the MLDS type here, avoids the need
% for this module to depend on back-end specific stuff like MLDS types.
:- type array_elem_type
---> elem_type_string % ml_string_type
; elem_type_int % mlds__native_int_type
; elem_type_generic % mlds__generic_type
.
% translate_builtin:
%
% Given a module name, a predicate name, a proc_id and a list of
% the arguments, find out if that procedure of that predicate
% is an inline builtin. If so, return code which can be used
% to evaluate that call: either an assignment (if the builtin is det)
% or a test (if the builtin is semidet).
%
% There are some further guarantees on the form of the expressions
% in the code returned -- see below for details.
% (bytecode_gen.m depends on these guarantees.)
%
:- pred translate_builtin(module_name, string, proc_id, list(T),
simple_code(T)).
:- mode translate_builtin(in, in, in, in, out(simple_code)) is semidet.
:- type simple_code(T)
---> assign(T, simple_expr(T))
; test(simple_expr(T)).
:- type simple_expr(T)
---> leaf(T)
; int_const(int)
; float_const(float)
; unary(unary_op, simple_expr(T))
; binary(binary_op, simple_expr(T), simple_expr(T)).
% Each test expression returned is guaranteed to be either a unary
% or binary operator, applied to arguments that are either variables
% (from the argument list) or constants.
%
% Each to be assigned expression is guaranteed to be either in a form
% acceptable for a test rval, or in the form of a variable.
:- inst simple_code
---> assign(ground, simple_assign_expr)
; test(simple_test_expr).
:- inst simple_arg_expr
---> leaf(ground)
; int_const(ground)
; float_const(ground).
:- inst simple_test_expr
---> unary(ground, simple_arg_expr)
; binary(ground, simple_arg_expr, simple_arg_expr).
:- inst simple_assign_expr
---> unary(ground, simple_arg_expr)
; binary(ground, simple_arg_expr, simple_arg_expr)
; leaf(ground).
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
:- implementation.
%-----------------------------------------------------------------------------%
translate_builtin(FullyQualifiedModule, PredName, ProcId, Args, Code) :-
proc_id_to_int(ProcId, ProcInt),
% -- not yet:
% FullyQualifiedModule = qualified(unqualified("std"), ModuleName),
FullyQualifiedModule = unqualified(ModuleName),
builtin_translation(ModuleName, PredName, ProcInt, Args, Code).
:- pred builtin_translation(string, string, int, list(T), simple_code(T)).
:- mode builtin_translation(in, in, in, in, out) is semidet.
% Note that the code we generate for unsafe_type_cast is not
% type-correct. Back-ends that require type-correct intermediate
% code (e.g. the MLDS back-end) must handle unsafe_type_cast
% separately, rather than by calling builtin_translation.
builtin_translation("private_builtin", "unsafe_type_cast", 0,
[X, Y], assign(Y, leaf(X))).
builtin_translation("builtin", "unsafe_promise_unique", 0,
[X, Y], assign(Y, leaf(X))).
builtin_translation("private_builtin", "builtin_int_gt", 0, [X, Y],
test(binary((>), leaf(X), leaf(Y)))).
builtin_translation("private_builtin", "builtin_int_lt", 0, [X, Y],
test(binary((<), leaf(X), leaf(Y)))).
builtin_translation("int", "+", 0, [X, Y, Z],
assign(Z, binary((+), leaf(X), leaf(Y)))).
builtin_translation("int", "+", 1, [X, Y, Z],
assign(X, binary((-), leaf(Z), leaf(Y)))).
builtin_translation("int", "+", 2, [X, Y, Z],
assign(Y, binary((-), leaf(Z), leaf(X)))).
builtin_translation("int", "-", 0, [X, Y, Z],
assign(Z, binary((-), leaf(X), leaf(Y)))).
builtin_translation("int", "-", 1, [X, Y, Z],
assign(X, binary((+), leaf(Y), leaf(Z)))).
builtin_translation("int", "-", 2, [X, Y, Z],
assign(Y, binary((-), leaf(X), leaf(Z)))).
builtin_translation("int", "*", 0, [X, Y, Z],
assign(Z, binary((*), leaf(X), leaf(Y)))).
builtin_translation("int", "unchecked_quotient", 0, [X, Y, Z],
assign(Z, binary((/), leaf(X), leaf(Y)))).
builtin_translation("int", "unchecked_rem", 0, [X, Y, Z],
assign(Z, binary((mod), leaf(X), leaf(Y)))).
builtin_translation("int", "unchecked_left_shift", 0, [X, Y, Z],
assign(Z, binary((<<), leaf(X), leaf(Y)))).
builtin_translation("int", "unchecked_right_shift", 0, [X, Y, Z],
assign(Z, binary((>>), leaf(X), leaf(Y)))).
builtin_translation("int", "/\\", 0, [X, Y, Z],
assign(Z, binary((&), leaf(X), leaf(Y)))).
builtin_translation("int", "\\/", 0, [X, Y, Z],
assign(Z, binary(('|'), leaf(X), leaf(Y)))).
builtin_translation("int", "xor", 0, [X, Y, Z],
assign(Z, binary((^), leaf(X), leaf(Y)))).
builtin_translation("int", "xor", 1, [X, Y, Z],
assign(Y, binary((^), leaf(X), leaf(Z)))).
builtin_translation("int", "xor", 2, [X, Y, Z],
assign(X, binary((^), leaf(Y), leaf(Z)))).
builtin_translation("int", "+", 0, [X, Y],
assign(Y, leaf(X))).
builtin_translation("int", "-", 0, [X, Y],
assign(Y, binary((-), int_const(0), leaf(X)))).
builtin_translation("int", "\\", 0, [X, Y],
assign(Y, unary(bitwise_complement, leaf(X)))).
builtin_translation("int", ">", 0, [X, Y],
test(binary((>), leaf(X), leaf(Y)))).
builtin_translation("int", "<", 0, [X, Y],
test(binary((<), leaf(X), leaf(Y)))).
builtin_translation("int", ">=", 0, [X, Y],
test(binary((>=), leaf(X), leaf(Y)))).
builtin_translation("int", "=<", 0, [X, Y],
test(binary((<=), leaf(X), leaf(Y)))).
builtin_translation("float", "+", 0, [X, Y, Z],
assign(Z, binary(float_plus, leaf(X), leaf(Y)))).
builtin_translation("float", "-", 0, [X, Y, Z],
assign(Z, binary(float_minus, leaf(X), leaf(Y)))).
builtin_translation("float", "*", 0, [X, Y, Z],
assign(Z, binary(float_times, leaf(X), leaf(Y)))).
builtin_translation("float", "unchecked_quotient", 0, [X, Y, Z],
assign(Z, binary(float_divide, leaf(X), leaf(Y)))).
builtin_translation("float", "+", 0, [X, Y],
assign(Y, leaf(X))).
builtin_translation("float", "-", 0, [X, Y],
assign(Y, binary(float_minus, float_const(0.0), leaf(X)))).
builtin_translation("float", ">", 0, [X, Y],
test(binary(float_gt, leaf(X), leaf(Y)))).
builtin_translation("float", "<", 0, [X, Y],
test(binary(float_lt, leaf(X), leaf(Y)))).
builtin_translation("float", ">=", 0, [X, Y],
test(binary(float_ge, leaf(X), leaf(Y)))).
builtin_translation("float", "=<", 0, [X, Y],
test(binary(float_le, leaf(X), leaf(Y)))).