[m-rev.] for review: add builtin 64-bit integer types -- Part 1

Julien Fischer jfischer at opturion.com
Fri Jan 12 13:45:51 AEDT 2018


Hi all,

The attached change begins the process of adding 64-bit integer types.
Once it is committed everyone will need to update their compiler before
part 2 is committed.

Julien.
-------------- next part --------------
Add builtin 64-bit integer types -- Part 1.

Add the new builitn types: int64 and uint64.
Support for these new types will need to be bootstrapped over several changes.
This is the first such change and does the following:

- Extends the compiler to recognise 'int64' and 'uint64' as builtin types.
- Extends the set of builtin arithmetic, bitwise and relational operators
  to cover the new types.
- Adds the new internal option '--unboxed-int64s' to the compiler; this will be
  used to control whether 64-bit integer types are boxed or not.
- Extends all of the code generators to handle the new types.
- Extends the runtimes to support the new types.
- Adds new modules to the standard library intend to contain basic operations
  on the new types.  (These are currently empty and not documented.)

There are bunch of limitations marks with "XXX INT64"; these will be lifted in
part 2 of this change.  Also, 64-bit integer types are currently always boxed,
again this limitation will be lifted in later changes.

compiler/options.m:
    Add the new option --unboxed-int64s.

compiler/prog_type.m:
compiler/prog_data.m:
compiler/builtin_lib_types.m:
     Recognise int64 and uint64 as builitn types. 

compiler/builtin_ops.m:
     Add builtin operations for the new types.

compiler/hlds_data.m:
     Add new tag types for the new types.

compiler/ctgc.selector.m:
compiler/dead_proc_elim.m:
compiler/export.m:
compiler/foreign.m:
compiler/goal_util.m:
compiler/higher_order.m:
compiler/hlds_code_util.m:
compiler/hlds_dependency_graph.m:
compiler/hlds_out_pred.m:
compiler/hlds_out_util.m:
compiler/implementation_defined_literals.m:
compiler/inst_check.m:
compiler/mercury_to_mercury.m:
compiler/mode_util.m:
compiler/module_qual.qualify_items.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/parse_tree_to_term.m:
compiler/parse_type_name.m:
compiler/polymoprhism.m:
compiler/prog_out.m:
compiler/prog_util.m:
compiler/rbmm.execution_path.m:
compiler/rtti.m:
compiler/table_gen.m:
compiler/type_util.m:
compiler/typecheck.m:
compiler/unify_gen.m:
compiler/unify_proc.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
    Conform to the above changes to the parse tree and HLDS.

compiler/c_util.m:
    Support writing out constants of the new types.

compiler/llds.m:
    Add a representation for constants of the new types to the LLDS.

compiler/stack_layout.m:
    Add a new field to the stack layout params that records whether
    64-bit integers are boxed or not.

compiler/call_gen.:m
compiler/code_info.m:
compiler/disj_gen.m:
compiler/dupproc.m:
compiler/exprn_aux.m:
compiler/global_data.m:
compiler/jumpopt.m:
compiler/llds_out_data.m:
compiler/llds_out_instr.m:
compiler/lookup_switch.m:
compiler/mercury_compile_llds_back_end.m:
compiler/prog_rep.m:
compiler/prog_rep_tables.m:
compiler/var_locn.m b/compiler/var_locn.m:
    Support the new types in the LLDS code generator.

compiler/mlds.m:
    Support constants of the new types in the MLDS.

compiler/ml_call_gen.m:
compiler/ml_code_util.m:
compiler/ml_global_data.m:
compiler/ml_rename_classes.m:
compiler/ml_top_gen.m:
compiler/ml_type_gen.m:
compiler/ml_unify_gen.m:
compiler/ml_util.m:
compiler/mlds_to_target_util.m:
compiler/rtti_to_mlds.m:
     Conform to the above changes to the MLDS.

compiler/mlds_to_c.m:
compiler/mlds_to_cs.m:
compiler/mlds_to_java.m:
    Generate the appropriate target code for constants of the new types
    and operations involving them.

compiler/bytecode.m:
compiler/bytecode_gen.m:
    Handle the new types in the bytecode generator; we just abort if we
    encounter them for now.

compiler/elds.m:
compiler/elds_to_erlang.m:
compiler/erl_call_gen.m:
compiler/erl_code_util.m:
compiler/erl_unify_gen.m:
    Handle the new types in the Erlang code generator.

library/private_builtin.m:
    Add placeholders for the builtin unify and compare operations for
    the new types.  Since the bootstrapping compiler will not recognise
    the new types we give the polymorphic arguments.  These can be
    replaced after this change has bootstrapped.
    
    Update the Java list of TypeCtorRep constants here.

library/int64.m:
library/uint64.m:
    New modules that will eventually contain builtin operations on the new
    types.

library/library.m:
library/MODULES_UNDOC:
    Do not include the above modules in the library documentation for now.

library/construct.m:
library/erlang_rtti_implementation.m:
library/rtti_implementation.m:
library/table_statistics.m:
deep_profiler/program_representation_utils.m:
mdbcomp/program_representation.m:
    Handle the new types.

configure.ac:
runtime/mercury_conf.h.in:
    Define the macro MR_BOXED_INT64S.  For now it is always defined, support for
    unboxed 64-bit integers will be enabled in a later change.

runtime/mercury_dotnet.cs.in:
java/runtime/TypeCtorRep.java:
runtime/mercury_type_info.h:
    Update the list of type_ctor reps.

runtime/mercury.h:
runtime/mercury_int.[ch]:
    Add macros for int64 / uint64 -> MR_Word conversion, boxing and
    unboxing.

    Add functions for hashing 64-bit integer types suitable for use
    with the tabling mechanism.

runtime/mercury_tabling.[ch]:
    Add additional HashTableSlot structs for 64-bit integer types.

    Omit the '%' character from the conversion specifiers we pass via
    the 'key_format' argument to the macros that generate the table lookup
    function.  This is so we can use the C99 exact size integer conversion
    specifiers (e.g. PRIu64 etc.) directly here.

runtime/mercury_hash_lookup_or_add_body.h:
    Add the '%' character that was omitted above to the call to debug_key_msg.
    
runtime/mercury_memory.h:
     Add new builtin allocation sites for boxed 64-bit integer types.

runtime/mercury_builtin_types.[ch]:
runtime/mercury_builitn_types_proc_layouts.h:
runtime/mercury_construct.c:
runtime/mercury_deconstruct.c:
runtime/mercury_deep_copy_body.h:
runtime/mercury_ml_expand_body.h:
runtime/mercury_table_type_body.h:
runtime/mercury_tabling_macros.h:
runtime/mercury_tabling_preds.h:
runtime/mercury_term_size.c:
runtime/mercury_unify_compare_body.h:
    Add the new builtin types and handle them throughout the runtime.

runtime/Mmakefile:
    Add mercury_int.c to the list of .c files.

doc/reference_manual.texi:
     Add the new types to the list of reserved type names.

     Add the mapping from the new types to their target language types.
     These are commented out for now.
-------------- next part --------------
diff --git a/compiler/builtin_lib_types.m b/compiler/builtin_lib_types.m
index 7f33a3b..f1f7cfe 100644
--- a/compiler/builtin_lib_types.m
+++ b/compiler/builtin_lib_types.m
@@ -72,6 +72,8 @@
 :- func uint16_type_ctor = type_ctor.
 :- func int32_type_ctor = type_ctor.
 :- func uint32_type_ctor = type_ctor.
+:- func int64_type_ctor = type_ctor.
+:- func uint64_type_ctor = type_ctor.
 :- func float_type_ctor = type_ctor.
 :- func char_type_ctor = type_ctor.
 :- func string_type_ctor = type_ctor.
@@ -254,6 +256,10 @@ int32_type_ctor = type_ctor(Name, 0) :-
     Name = unqualified("int32").
 uint32_type_ctor = type_ctor(Name, 0) :-
     Name = unqualified("uint32").
+int64_type_ctor = type_ctor(Name, 0) :-
+    Name = unqualified("int64").
+uint64_type_ctor = type_ctor(Name, 0) :-
+    Name = unqualified("uint64").
 float_type_ctor = type_ctor(Name, 0) :-
     Name = unqualified("float").
 char_type_ctor = type_ctor(Name, 0) :-
diff --git a/compiler/builtin_ops.m b/compiler/builtin_ops.m
index 3617b2e..62e459e 100644
--- a/compiler/builtin_ops.m
+++ b/compiler/builtin_ops.m
@@ -178,6 +178,8 @@
     ;       uint16_const(uint16)
     ;       int32_const(int32)
     ;       uint32_const(uint32)
+    ;       int64_const(int) % XXX INT64
+    ;       uint64_const(int) % XX INT64
     ;       float_const(float)
     ;       unary(unary_op, simple_expr(T))
     ;       binary(binary_op, simple_expr(T), simple_expr(T)).
@@ -314,6 +316,8 @@ builtin_translation(ModuleName, PredName, ProcNum, Args, Code) :-
         ; ModuleName = "uint16", IntType = int_type_uint16
         ; ModuleName = "int32", IntType = int_type_int32
         ; ModuleName = "uint32", IntType = int_type_uint32
+        ; ModuleName = "int64", IntType = int_type_int64
+        ; ModuleName = "uint64", IntType = int_type_uint64
         ),
         (
             PredName = "+",
diff --git a/compiler/bytecode.m b/compiler/bytecode.m
index 3281b9e..79dd218 100644
--- a/compiler/bytecode.m
+++ b/compiler/bytecode.m
@@ -1188,6 +1188,38 @@ binop_code(bitwise_or(int_type_uint32),  153).
 binop_code(bitwise_xor(int_type_uint32), 154).
 binop_code(unchecked_left_shift(int_type_uint32),  155).
 binop_code(unchecked_right_shift(int_type_uint32), 156).
+binop_code(eq(int_type_int64),       157).
+binop_code(ne(int_type_int64),       158).
+binop_code(int_lt(int_type_int64),   159).
+binop_code(int_gt(int_type_int64),   160).
+binop_code(int_le(int_type_int64),   161).
+binop_code(int_ge(int_type_int64),   162).
+binop_code(int_add(int_type_int64),  163).
+binop_code(int_sub(int_type_int64),  164).
+binop_code(int_mul(int_type_int64),  165).
+binop_code(int_div(int_type_int64),  166).
+binop_code(int_mod(int_type_int64),  167).
+binop_code(bitwise_and(int_type_int64), 168).
+binop_code(bitwise_or(int_type_int64),  169).
+binop_code(bitwise_xor(int_type_int64), 170).
+binop_code(unchecked_left_shift(int_type_int64), 171).
+binop_code(unchecked_right_shift(int_type_int64), 172).
+binop_code(eq(int_type_uint64),       173).
+binop_code(ne(int_type_uint64),       174).
+binop_code(int_lt(int_type_uint64),   175).
+binop_code(int_gt(int_type_uint64),   176).
+binop_code(int_le(int_type_uint64),   177).
+binop_code(int_ge(int_type_uint64),   178).
+binop_code(int_add(int_type_uint64),  179).
+binop_code(int_sub(int_type_uint64),  180).
+binop_code(int_mul(int_type_uint64),  181).
+binop_code(int_div(int_type_uint64),  182).
+binop_code(int_mod(int_type_uint64),  183).
+binop_code(bitwise_and(int_type_uint64), 184).
+binop_code(bitwise_or(int_type_uint64),  185).
+binop_code(bitwise_xor(int_type_uint64), 186).
+binop_code(unchecked_left_shift(int_type_uint64),  187).
+binop_code(unchecked_right_shift(int_type_uint64), 188).
 
 :- pred binop_debug(binary_op::in, string::out) is det.
 
@@ -1348,6 +1380,38 @@ binop_debug(bitwise_or(int_type_uint32),  "|(uint32)").
 binop_debug(bitwise_xor(int_type_uint32), "^(uint32)").
 binop_debug(unchecked_left_shift(int_type_uint32), "<<(uint32)").
 binop_debug(unchecked_right_shift(int_type_uint32), ">>(uint32)").
+binop_debug(eq(int_type_int64),      "==(int64)").
+binop_debug(ne(int_type_int64),      "!=(int64)").
+binop_debug(int_lt(int_type_int64),  "<(int64)").
+binop_debug(int_gt(int_type_int64),  ">(int64)").
+binop_debug(int_le(int_type_int64),  "<=(int64)").
+binop_debug(int_ge(int_type_int64),  ">=(int64)").
+binop_debug(int_add(int_type_int64), "+(int64)").
+binop_debug(int_sub(int_type_int64), "-(int64)").
+binop_debug(int_mul(int_type_int64), "*(int64)").
+binop_debug(int_div(int_type_int64), "/(int64)").
+binop_debug(int_mod(int_type_int64), "mod(int64)").
+binop_debug(bitwise_and(int_type_int64), "&(int64)").
+binop_debug(bitwise_or(int_type_int64), "|(int64)").
+binop_debug(bitwise_xor(int_type_int64), "^(int64)").
+binop_debug(unchecked_left_shift(int_type_int64), "<<(int64)").
+binop_debug(unchecked_right_shift(int_type_int64), ">>(int64)").
+binop_debug(eq(int_type_uint64),      "==(uint64)").
+binop_debug(ne(int_type_uint64),      "!=(uint64)").
+binop_debug(int_lt(int_type_uint64),  "<(uint64)").
+binop_debug(int_gt(int_type_uint64),  ">(uint64)").
+binop_debug(int_le(int_type_uint64),  "<=(uint64)").
+binop_debug(int_ge(int_type_uint64),  ">=(uint64)").
+binop_debug(int_add(int_type_uint64), "+(uint64)").
+binop_debug(int_sub(int_type_uint64), "-(uint64)").
+binop_debug(int_mul(int_type_uint64), "*(uint64)").
+binop_debug(int_div(int_type_uint64), "/(uint64)").
+binop_debug(int_mod(int_type_uint64), "mod(uint64").
+binop_debug(bitwise_and(int_type_uint64), "&(uint64)").
+binop_debug(bitwise_or(int_type_uint64),  "|(uint64)").
+binop_debug(bitwise_xor(int_type_uint64), "^(uint64)").
+binop_debug(unchecked_left_shift(int_type_uint64), "<<(uint64)").
+binop_debug(unchecked_right_shift(int_type_uint64), ">>(uint64)").
 
 :- pred unop_code(unary_op::in, int::out) is det.
 
@@ -1372,6 +1436,8 @@ unop_code(bitwise_complement(int_type_int16), 17).
 unop_code(bitwise_complement(int_type_uint16), 18).
 unop_code(bitwise_complement(int_type_int32), 19).
 unop_code(bitwise_complement(int_type_uint32), 20).
+unop_code(bitwise_complement(int_type_int64), 21).
+unop_code(bitwise_complement(int_type_uint64), 22).
 
 :- pred unop_debug(unary_op::in, string::out) is det.
 
@@ -1396,6 +1462,8 @@ unop_debug(bitwise_complement(int_type_int16), "bitwise_complement(int16)").
 unop_debug(bitwise_complement(int_type_uint16), "bitwise_complement(uint16)").
 unop_debug(bitwise_complement(int_type_int32), "bitwise_complement(int32)").
 unop_debug(bitwise_complement(int_type_uint32), "bitwise_complement(uint32)").
+unop_debug(bitwise_complement(int_type_int64), "bitwise_complement(int64)").
+unop_debug(bitwise_complement(int_type_uint64), "bitwise_complement(uint64)").
 
 %---------------------------------------------------------------------------%
 
diff --git a/compiler/bytecode_gen.m b/compiler/bytecode_gen.m
index 3107ee9..227b7e1 100644
--- a/compiler/bytecode_gen.m
+++ b/compiler/bytecode_gen.m
@@ -599,6 +599,12 @@ gen_unify(Unification, ByteInfo, Code) :-
             TypeCategory = ctor_cat_builtin(cat_builtin_int(int_type_uint32)),
             sorry($module, $pred, "uint32")
         ;
+            TypeCategory = ctor_cat_builtin(cat_builtin_int(int_type_int64)),
+            sorry($module, $pred, "int64")
+        ;
+            TypeCategory = ctor_cat_builtin(cat_builtin_int(int_type_uint64)),
+            sorry($module, $pred, "uint64")
+        ;
             TypeCategory = ctor_cat_builtin(cat_builtin_char),
             TestId = char_test
         ;
@@ -805,6 +811,12 @@ map_cons_id(ByteInfo, ConsId, ByteConsId) :-
         ConsId = uint32_const(_),
         unexpected($file, $pred, "uint32")
     ;
+        ConsId = int64_const(_),
+        unexpected($file, $pred, "int64")
+    ;
+        ConsId = uint64_const(_),
+        unexpected($file, $pred, "uint64")
+    ;
         ConsId = float_const(FloatVal),
         ByteConsId = byte_float_const(FloatVal)
     ;
@@ -878,6 +890,8 @@ map_cons_tag(int_tag(IntTagType), ByteConsTag) :-
         ; IntTagType = int_tag_uint16(_)
         ; IntTagType = int_tag_int32(_)
         ; IntTagType = int_tag_uint32(_)
+        ; IntTagType = int_tag_int64(_)
+        ; IntTagType = int_tag_uint64(_)
         ),
         sorry($module, $pred, "bytecode with uint or fixed size int")
     ).
diff --git a/compiler/c_util.m b/compiler/c_util.m
index 6920c75..4268f80 100644
--- a/compiler/c_util.m
+++ b/compiler/c_util.m
@@ -221,6 +221,18 @@
     io::di, io::uo) is det.
 :- pred output_uint32_expr_cur_stream(uint32::in, io::di, io::uo) is det.
 
+    % Write out an int64 as a C expression.
+    %
+:- pred output_int64_expr(io.text_output_stream::in, int::in,
+    io::di, io::uo) is det.
+:- pred output_int64_expr_cur_stream(int::in, io::di, io::uo) is det.
+
+    % Write out a uint64 as a C expression.
+    %
+:- pred output_uint64_expr(io.text_output_stream::in, int::in,
+    io::di, io::uo) is det.
+:- pred output_uint64_expr_cur_stream(int::in, io::di, io::uo) is det.
+
 %---------------------------------------------------------------------------%
 %
 % Float literals.
@@ -876,6 +888,24 @@ output_uint32_expr_cur_stream(N, !IO) :-
     io.output_stream(Stream, !IO),
     output_uint32_expr(Stream, N, !IO).
 
+output_int64_expr(Stream, N, !IO) :-
+    io.write_string(Stream, "INT64_C(", !IO),
+    io.write_int(Stream, N, !IO),
+    io.write_string(Stream, ")", !IO).
+
+output_int64_expr_cur_stream(N, !IO) :-
+    io.output_stream(Stream, !IO),
+    output_int64_expr(Stream, N, !IO).
+
+output_uint64_expr(Stream, N, !IO) :-
+    io.write_string(Stream, "UINT64_C(", !IO),
+    io.write_int(Stream, N, !IO),
+    io.write_string(Stream, ")", !IO).
+
+output_uint64_expr_cur_stream(N, !IO) :-
+    io.output_stream(Stream, !IO),
+    output_uint64_expr(Stream, N, !IO).
+
 %---------------------------------------------------------------------------%
 %
 % Floating point literals.
diff --git a/compiler/call_gen.m b/compiler/call_gen.m
index 11ad7f0..0dada6b 100644
--- a/compiler/call_gen.m
+++ b/compiler/call_gen.m
@@ -753,6 +753,8 @@ convert_simple_expr(int16_const(Int16)) = const(llconst_int16(Int16)).
 convert_simple_expr(uint16_const(UInt16)) = const(llconst_uint16(UInt16)).
 convert_simple_expr(int32_const(Int32)) = const(llconst_int32(Int32)).
 convert_simple_expr(uint32_const(UInt32)) = const(llconst_uint32(UInt32)).
+convert_simple_expr(int64_const(Int64)) = const(llconst_int64(Int64)).
+convert_simple_expr(uint64_const(UInt64)) = const(llconst_uint64(UInt64)).
 convert_simple_expr(float_const(Float)) = const(llconst_float(Float)).
 convert_simple_expr(unary(UnOp, Expr)) =
     unop(UnOp, convert_simple_expr(Expr)).
diff --git a/compiler/code_info.m b/compiler/code_info.m
index ae5ef3f..bf542f5 100644
--- a/compiler/code_info.m
+++ b/compiler/code_info.m
@@ -529,8 +529,16 @@ init_exprn_opts(Globals) = ExprnOpts :-
         OptStaticCodeAddr = no,
         StaticCodeAddrs = do_not_have_static_code_addresses
     ),
+    globals.lookup_bool_option(Globals, unboxed_int64s, OptUBI64s),
+    (
+        OptUBI64s = yes,
+        UBI64s = have_unboxed_int64s
+    ;
+        OptUBI64s = no,
+        UBI64s = do_not_have_unboxed_int64s
+    ),
     ExprnOpts = exprn_opts(NLG, ASM, UBF, UseFloatRegs, DetStackFloatWidth,
-        SGCell, SGFloat, StaticCodeAddrs).
+        SGCell, SGFloat, StaticCodeAddrs, UBI64s).
 
 :- pred max_var_slot(stack_slots::in, int::out) is det.
 
diff --git a/compiler/ctgc.selector.m b/compiler/ctgc.selector.m
index 928cf65..7a043f0 100644
--- a/compiler/ctgc.selector.m
+++ b/compiler/ctgc.selector.m
@@ -123,6 +123,8 @@ selector_init(ConsId, Index) = [TermSel] :-
         ; ConsId = uint16_const(_)
         ; ConsId = int32_const(_)
         ; ConsId = uint32_const(_)
+        ; ConsId = int64_const(_)
+        ; ConsId = uint64_const(_)
         ; ConsId = float_const(_)
         ; ConsId = char_const(_)
         ; ConsId = string_const(_)
diff --git a/compiler/dead_proc_elim.m b/compiler/dead_proc_elim.m
index 76ba085..4db9a66 100644
--- a/compiler/dead_proc_elim.m
+++ b/compiler/dead_proc_elim.m
@@ -825,6 +825,8 @@ dead_proc_examine_goal(Goal, CurrProc, !Queue, !Needed) :-
                 ; ConsId = uint16_const(_)
                 ; ConsId = int32_const(_)
                 ; ConsId = uint32_const(_)
+                ; ConsId = int64_const(_)
+                ; ConsId = uint64_const(_)
                 ; ConsId = float_const(_)
                 ; ConsId = char_const(_)
                 ; ConsId = string_const(_)
diff --git a/compiler/disj_gen.m b/compiler/disj_gen.m
index 64ae455..5414053 100644
--- a/compiler/disj_gen.m
+++ b/compiler/disj_gen.m
@@ -202,7 +202,9 @@ is_lookup_disj(AddTrailOps, AddRegionOps, ResumeVars, Disjuncts, DisjGoalInfo,
 
     get_exprn_opts(!.CI, ExprnOpts),
     UnboxFloats = get_unboxed_floats(ExprnOpts),
-    find_general_llds_types(UnboxFloats, OutTypes, Solns, LLDSTypes),
+    UnboxInt64s = get_unboxed_int64s(ExprnOpts),
+    find_general_llds_types(UnboxFloats, UnboxInt64s, OutTypes, Solns,
+        LLDSTypes),
     LookupDisjInfo = lookup_disj_info(OutVars, StoreMap, MaybeEnd, Liveness,
         CurSlot, ResumeMap, FlushCode, SaveTicketCode, MaybeTicketSlot,
         SaveHpCode, MaybeHpSlot, HijackInfo, PrepareHijackCode,
diff --git a/compiler/dupproc.m b/compiler/dupproc.m
index 57db913..9270cd2 100644
--- a/compiler/dupproc.m
+++ b/compiler/dupproc.m
@@ -417,6 +417,8 @@ standardize_rval_const(Const, StdConst, DupProcMap) :-
         ; Const = llconst_uint16(_)
         ; Const = llconst_int32(_)
         ; Const = llconst_uint32(_)
+        ; Const = llconst_int64(_)
+        ; Const = llconst_uint64(_)
         ; Const = llconst_foreign(_, _)
         ; Const = llconst_float(_)
         ; Const = llconst_string(_)
diff --git a/compiler/elds.m b/compiler/elds.m
index 7dccebd..c5a5ee1 100644
--- a/compiler/elds.m
+++ b/compiler/elds.m
@@ -222,6 +222,8 @@
     ;       elds_uint16(uint16)
     ;       elds_int32(int32)
     ;       elds_uint32(uint32)
+    ;       elds_int64(int)    % XXX INT64.
+    ;       elds_uint64(int)   % XXX INT64.
     ;       elds_float(float)
 
     ;       elds_binary(string)
diff --git a/compiler/elds_to_erlang.m b/compiler/elds_to_erlang.m
index 6f22fc4..b60394e 100644
--- a/compiler/elds_to_erlang.m
+++ b/compiler/elds_to_erlang.m
@@ -811,6 +811,14 @@ output_term(ModuleInfo, VarSet, Indent, Term, !IO) :-
         output_float(Float, !IO),
         space(!IO)
     ;
+        Term = elds_int64(Int64),
+        io.write_int(Int64, !IO),   % XXX INT64.
+        space(!IO)
+    ;
+        Term = elds_uint64(UInt64),
+        io.write_int(UInt64, !IO),  % XXX INT64.
+        space(!IO)
+    ;
         Term = elds_binary(String),
         io.write_string("<<""", !IO),
         write_with_escaping(in_string, String, !IO),
diff --git a/compiler/erl_call_gen.m b/compiler/erl_call_gen.m
index 0831bc9..c84eda1 100644
--- a/compiler/erl_call_gen.m
+++ b/compiler/erl_call_gen.m
@@ -467,6 +467,12 @@ erl_gen_simple_expr(ModuleInfo, VarTypes, SimpleExpr) = Expr :-
         SimpleExpr = uint32_const(UInt32),
         Expr = elds_term(elds_uint32(UInt32))
     ;
+        SimpleExpr = int64_const(Int64),
+        Expr = elds_term(elds_int64(Int64))
+    ;
+        SimpleExpr = uint64_const(UInt64),
+        Expr = elds_term(elds_uint64(UInt64))
+    ;
         SimpleExpr = float_const(Float),
         Expr = elds_term(elds_float(Float))
     ;
diff --git a/compiler/erl_code_util.m b/compiler/erl_code_util.m
index 8ff48eb..c4db8d5 100644
--- a/compiler/erl_code_util.m
+++ b/compiler/erl_code_util.m
@@ -563,6 +563,8 @@ erl_rename_vars_in_term(Subn, Term0, Term) :-
         ; Term0 = elds_uint16(_)
         ; Term0 = elds_int32(_)
         ; Term0 = elds_uint32(_)
+        ; Term0 = elds_int64(_)
+        ; Term0 = elds_uint64(_)
         ; Term0 = elds_float(_)
         ; Term0 = elds_binary(_)
         ; Term0 = elds_list_of_ints(_)
@@ -734,6 +736,8 @@ erl_vars_in_term(Term, !Set) :-
         ; Term = elds_uint16(_)
         ; Term = elds_int32(_)
         ; Term = elds_uint32(_)
+        ; Term = elds_int64(_)
+        ; Term = elds_uint64(_)
         ; Term = elds_float(_)
         ; Term = elds_binary(_)
         ; Term = elds_list_of_ints(_)
@@ -879,6 +883,8 @@ erl_term_size(Term) = Size :-
         ; Term = elds_uint16(_)
         ; Term = elds_int32(_)
         ; Term = elds_uint32(_)
+        ; Term = elds_int64(_)
+        ; Term = elds_uint64(_)
         ; Term = elds_float(_)
         ; Term = elds_binary(_)
         ; Term = elds_list_of_ints(_)
@@ -1007,6 +1013,8 @@ non_variable_term(Term) :-
         ; Term = elds_uint16(_)
         ; Term = elds_int32(_)
         ; Term = elds_uint32(_)
+        ; Term = elds_int64(_)
+        ; Term = elds_uint64(_)
         ; Term = elds_float(_)
         ; Term = elds_binary(_)
         ; Term = elds_list_of_ints(_)
diff --git a/compiler/erl_unify_gen.m b/compiler/erl_unify_gen.m
index a1e0fa4..7e465e3 100644
--- a/compiler/erl_unify_gen.m
+++ b/compiler/erl_unify_gen.m
@@ -72,6 +72,8 @@
     ;       uint16_const(ground)
     ;       int32_const(ground)
     ;       uint32_const(ground)
+    ;       int64_const(ground)
+    ;       uint64_const(ground)
     ;       float_const(ground)
     ;       char_const(ground)
     ;       string_const(ground).
@@ -306,6 +308,12 @@ cons_id_to_term(ConsId, Args, DummyVarReplacement, Term, !Info) :-
         ConsId = uint32_const(UInt32),
         Term = elds_uint32(UInt32)
     ;
+        ConsId = int64_const(Int64),
+        Term = elds_int64(Int64)
+    ;
+        ConsId = uint64_const(UInt64),
+        Term = elds_uint64(UInt64)
+    ;
         ConsId = float_const(Float),
         Term = elds_float(Float)
     ;
@@ -328,6 +336,8 @@ cons_id_to_expr(ConsId, Args, DummyVarReplacement, Expr, !Info) :-
         ; ConsId = uint16_const(_)
         ; ConsId = int32_const(_)
         ; ConsId = uint32_const(_)
+        ; ConsId = int64_const(_)
+        ; ConsId = uint64_const(_)
         ; ConsId = float_const(_)
         ; ConsId = char_const(_)
         ; ConsId = string_const(_)
diff --git a/compiler/export.m b/compiler/export.m
index df5d383..84af34c 100644
--- a/compiler/export.m
+++ b/compiler/export.m
@@ -653,8 +653,25 @@ convert_type_to_mercury(Rval, Type, TargetArgLoc, ConvertedRval) :-
             % is signed.
             ConvertedRval = "(MR_UnsignedChar) " ++ Rval
         ;
-            BuiltinType = builtin_type_int(_),
-            ConvertedRval = Rval
+            BuiltinType = builtin_type_int(IntType),
+            (
+                ( IntType = int_type_int
+                ; IntType = int_type_uint
+                ; IntType = int_type_int8
+                ; IntType = int_type_uint8
+                ; IntType = int_type_int16
+                ; IntType = int_type_uint16
+                ; IntType = int_type_int32
+                ; IntType = int_type_uint32
+                ),
+                ConvertedRval = Rval
+            ;
+                IntType = int_type_int64,
+                ConvertedRval = "MR_int64_to_word(" ++ Rval ++ ")"
+            ;
+                IntType = int_type_uint64,
+                ConvertedRval = "MR_uint64_to_word(" ++ Rval ++ ")"
+            )
         )
     ;
         ( Type = type_variable(_, _)
@@ -683,9 +700,27 @@ convert_type_from_mercury(SourceArgLoc, Rval, Type, ConvertedRval) :-
                 ConvertedRval = Rval
             )
         ;
-            ( BuiltinType = builtin_type_int(_)
-            ; BuiltinType = builtin_type_char
-            ),
+            BuiltinType = builtin_type_int(IntType),
+            (
+                ( IntType = int_type_int
+                ; IntType = int_type_uint
+                ; IntType = int_type_int8
+                ; IntType = int_type_uint8
+                ; IntType = int_type_int16
+                ; IntType = int_type_uint16
+                ; IntType = int_type_int32
+                ; IntType = int_type_uint32
+                ),
+                ConvertedRval = Rval
+            ;
+                IntType = int_type_int64,
+                ConvertedRval = "MR_word_to_int64(" ++ Rval ++ ")"
+            ;
+                IntType = int_type_uint64,
+                ConvertedRval = "MR_word_to_uint64(" ++ Rval ++ ")"
+            )
+        ;
+            BuiltinType = builtin_type_char,
             ConvertedRval = Rval
         )
     ;
@@ -961,6 +996,8 @@ foreign_const_name_and_tag(TypeCtor, Mapping, TagValues, Ctor,
             ; IntTagType = int_tag_uint16(_)
             ; IntTagType = int_tag_int32(_)
             ; IntTagType = int_tag_uint32(_)
+            ; IntTagType = int_tag_int64(_)
+            ; IntTagType = int_tag_uint64(_)
             ),
             unexpected($module, $pred, "enum constant requires an int tag")
         )
diff --git a/compiler/exprn_aux.m b/compiler/exprn_aux.m
index aeb7667..39b7a36 100644
--- a/compiler/exprn_aux.m
+++ b/compiler/exprn_aux.m
@@ -124,6 +124,12 @@ const_is_constant(Const, ExprnOpts, IsConst) :-
         ),
         IsConst = yes
     ;
+        ( Const = llconst_int64(_)
+        ; Const = llconst_uint64(_)
+        ),
+        % XXX INT64.
+        IsConst = yes
+    ;
         Const = llconst_float(_),
         SGFloats = ExprnOpts ^ static_ground_floats,
         (
diff --git a/compiler/foreign.m b/compiler/foreign.m
index 310f1fe..3a83b7d 100644
--- a/compiler/foreign.m
+++ b/compiler/foreign.m
@@ -319,6 +319,12 @@ exported_builtin_type_to_c_string(BuiltinType) = CTypeName :-
         ;
             IntType = int_type_uint32,
             CTypeName = "uint32_t"
+        ;
+            IntType = int_type_int64,
+            CTypeName = "int64_t"
+        ;
+            IntType = int_type_uint64,
+            CTypeName = "uint64_t"
         )
     ;
         BuiltinType = builtin_type_float,
@@ -358,6 +364,12 @@ exported_builtin_type_to_csharp_string(BuiltinType) = CsharpTypeName :-
         ;
             IntType = int_type_uint32,
             CsharpTypeName = "uint"
+        ;
+            IntType = int_type_int64,
+            CsharpTypeName = "long"
+        ;
+            IntType = int_type_uint64,
+            CsharpTypeName = "ulong"
         )
     ;
         BuiltinType = builtin_type_float,
@@ -397,6 +409,12 @@ exported_builtin_type_to_java_string(BuiltinType) = JavaTypeName :-
         ;
             IntType = int_type_uint32,
             JavaTypeName = "int"
+        ;
+            IntType = int_type_int64,
+            JavaTypeName = "long"
+        ;
+            IntType = int_type_uint64,
+            JavaTypeName = "long"
         )
     ;
         BuiltinType = builtin_type_float,
diff --git a/compiler/global_data.m b/compiler/global_data.m
index 8daa37c..9fceb62 100644
--- a/compiler/global_data.m
+++ b/compiler/global_data.m
@@ -82,8 +82,8 @@
 
 :- type static_cell_info.
 
-:- func init_static_cell_info(module_name, have_unboxed_floats, bool)
-    = static_cell_info.
+:- func init_static_cell_info(module_name, have_unboxed_floats, bool,
+    have_unboxed_int64s) = static_cell_info.
 
 :- pred add_scalar_static_cell(list(typed_rval)::in, data_id::out,
     static_cell_info::in, static_cell_info::out) is det.
@@ -98,8 +98,9 @@
     list(alloc_site_info)::out, map(alloc_site_id, layout_slot_name)::out)
     is det.
 
-:- pred find_general_llds_types(have_unboxed_floats::in, list(mer_type)::in,
-    list(list(rval))::in, list(llds_type)::out) is semidet.
+:- pred find_general_llds_types(have_unboxed_floats::in,
+    have_unboxed_int64s::in, list(mer_type)::in, list(list(rval))::in,
+    list(llds_type)::out) is semidet.
 
 :- pred add_vector_static_cell(list(llds_type)::in,
     list(list(rval))::in, data_id::out,
@@ -112,13 +113,15 @@
     list(scalar_common_data_array)::out, list(vector_common_data_array)::out)
     is det.
 
-    % Given an rval, the value of the --unboxed_float option and the width of
-    % the constructor argument, figure out the type the rval would have as an
-    % argument. Normally that's the same as its usual type; the exception is
-    % that for boxed floats, the type is data_ptr (i.e. the type of the boxed
-    % value) rather than float (the type of the unboxed value).
+    % Given an rval, the value of the --unboxed-float option, the vlaue of the
+    % --unboxed-int64s and the width of the constructor argument, figure out
+    % the type the rval would have as an argument. Normally that's the same as
+    % its usual type; the exception is that for boxed floats, boxed int64s and
+    % boxed uint64s the type is data_ptr (i.e. the type of the boxed value)
+    % rather than float, int64, uint64 (the type of the unboxed value).
     %
-:- func rval_type_as_arg(have_unboxed_floats, arg_width, rval) = llds_type.
+:- func rval_type_as_arg(have_unboxed_floats,have_unboxed_int64s,  arg_width,
+    rval) = llds_type.
 
 %-----------------------------------------------------------------------------%
 
@@ -330,7 +333,8 @@ make_alloc_id_map(AllocSite, Slot, Slot + 1, !Map) :-
     --->    static_cell_sub_info(
                 scsi_module_name            :: module_name, % base file name
                 scsi_unbox_float            :: have_unboxed_floats,
-                scsi_common_data            :: bool
+                scsi_common_data            :: bool,
+                scsi_unbox_int64s           :: have_unboxed_int64s
             ).
 
 :- type cell_type_bimap == bimap(common_cell_type, type_num).
@@ -354,8 +358,9 @@ make_alloc_id_map(AllocSite, Slot, Slot + 1, !Map) :-
                 sci_vector_cell_group_map   :: vector_type_cell_map
             ).
 
-init_static_cell_info(BaseName, UnboxFloat, CommonData) = Info0 :-
-    SubInfo0 = static_cell_sub_info(BaseName, UnboxFloat, CommonData),
+init_static_cell_info(BaseName, UnboxFloat, CommonData, UnboxInt64s) = Info0 :-
+    SubInfo0 = static_cell_sub_info(BaseName, UnboxFloat, CommonData,
+        UnboxInt64s),
     Info0 = static_cell_info(SubInfo0, counter.init(0), bimap.init,
         map.init, map.init).
 
@@ -363,8 +368,10 @@ init_static_cell_info(BaseName, UnboxFloat, CommonData) = Info0 :-
 
 add_scalar_static_cell_natural_types(Args, DataId, !Info) :-
     UnboxFloat = !.Info ^ sci_sub_info ^ scsi_unbox_float,
+    UnboxInt64s = !.Info ^ sci_sub_info ^ scsi_unbox_int64s,
     ArgWidth = full_word,
-    list.map(associate_natural_type(UnboxFloat, ArgWidth), Args, TypedArgs),
+    list.map(associate_natural_type(UnboxFloat, UnboxInt64s, ArgWidth),
+        Args, TypedArgs),
     add_scalar_static_cell(TypedArgs, DataId, !Info).
 
 add_scalar_static_cell(TypedArgs0, DataId, !Info) :-
@@ -473,30 +480,32 @@ search_scalar_static_cell_offset(Info, DataId, Offset, Rval) :-
 
 %-----------------------------------------------------------------------------%
 
-find_general_llds_types(UnboxFloat, Types, [Vector | Vectors], LLDSTypes) :-
+find_general_llds_types(UnboxFloat, UnboxInt64s, Types, [Vector | Vectors],
+        LLDSTypes) :-
     ArgWidth = full_word,
-    list.map(natural_type(UnboxFloat, ArgWidth), Vector, LLDSTypes0),
-    find_general_llds_types_2(UnboxFloat, Types, Vectors,
+    list.map(natural_type(UnboxFloat, UnboxInt64s, ArgWidth), Vector,
+        LLDSTypes0),
+    find_general_llds_types_2(UnboxFloat, UnboxInt64s, Types, Vectors,
         LLDSTypes0, LLDSTypes).
 
-:- pred find_general_llds_types_2(have_unboxed_floats::in, list(mer_type)::in,
-    list(list(rval))::in, list(llds_type)::in, list(llds_type)::out)
-    is semidet.
+:- pred find_general_llds_types_2(have_unboxed_floats::in,
+    have_unboxed_int64s::in, list(mer_type)::in, list(list(rval))::in,
+    list(llds_type)::in, list(llds_type)::out) is semidet.
 
-find_general_llds_types_2(_UnboxFloat, _Types, [], !LLDSTypes).
-find_general_llds_types_2(UnboxFloat, Types, [Vector | Vectors], !LLDSTypes) :-
-    find_general_llds_types_in_cell(UnboxFloat, Types, Vector, !LLDSTypes),
-    find_general_llds_types_2(UnboxFloat, Types, Vectors, !LLDSTypes).
+find_general_llds_types_2(_UnboxFloat, _UnboxInt64s, _Types, [], !LLDSTypes).
+find_general_llds_types_2(UnboxFloat, UnboxInt64s, Types, [Vector | Vectors], !LLDSTypes) :-
+    find_general_llds_types_in_cell(UnboxFloat, UnboxInt64s, Types, Vector, !LLDSTypes),
+    find_general_llds_types_2(UnboxFloat, UnboxInt64s, Types, Vectors, !LLDSTypes).
 
 :- pred find_general_llds_types_in_cell(have_unboxed_floats::in,
-    list(mer_type)::in, list(rval)::in, list(llds_type)::in,
-    list(llds_type)::out) is semidet.
+    have_unboxed_int64s::in, list(mer_type)::in, list(rval)::in,
+    list(llds_type)::in, list(llds_type)::out) is semidet.
 
-find_general_llds_types_in_cell(_UnboxFloat, [], [], [], []).
-find_general_llds_types_in_cell(UnboxFloat, [_Type | Types], [Rval | Rvals],
-        [LLDSType0 | LLDSTypes0], [LLDSType | LLDSTypes]) :-
+find_general_llds_types_in_cell(_UnboxFloat, _UnboxInt64s, [], [], [], []).
+find_general_llds_types_in_cell(UnboxFloat, UnboxInt64s, [_Type | Types],
+        [Rval | Rvals], [LLDSType0 | LLDSTypes0], [LLDSType | LLDSTypes]) :-
     ArgWidth = full_word,
-    natural_type(UnboxFloat, ArgWidth, Rval, NaturalType),
+    natural_type(UnboxFloat, UnboxInt64s, ArgWidth, Rval, NaturalType),
     % For user-defined types, some function symbols may be constants
     % (whose representations yield integer rvals) while others may be
     % non-constants (whose representations yield data_ptr rvals).
@@ -524,7 +533,7 @@ find_general_llds_types_in_cell(UnboxFloat, [_Type | Types], [Rval | Rvals],
     else
         fail
     ),
-    find_general_llds_types_in_cell(UnboxFloat, Types, Rvals,
+    find_general_llds_types_in_cell(UnboxFloat, UnboxInt64s, Types, Rvals,
         LLDSTypes0, LLDSTypes).
 
 %-----------------------------------------------------------------------------%
@@ -689,13 +698,13 @@ make_arg_groups(Type, RevArgs, TypeGroup, TypeAndArgGroup) :-
 
 %-----------------------------------------------------------------------------%
 
-rval_type_as_arg(UnboxedFloat, ArgWidth, Rval) = Type :-
-    natural_type(UnboxedFloat, ArgWidth, Rval, Type).
+rval_type_as_arg(UnboxedFloat, UnboxedInt64s, ArgWidth, Rval) = Type :-
+    natural_type(UnboxedFloat, UnboxedInt64s, ArgWidth, Rval, Type).
 
-:- pred natural_type(have_unboxed_floats::in, arg_width::in, rval::in,
-    llds_type::out) is det.
+:- pred natural_type(have_unboxed_floats::in, have_unboxed_int64s::in,
+    arg_width::in, rval::in, llds_type::out) is det.
 
-natural_type(UnboxFloat, ArgWidth, Rval, Type) :-
+natural_type(UnboxFloat, UnboxInt64s, ArgWidth, Rval, Type) :-
     llds.rval_type(Rval, Type0),
     ( if
         Type0 = lt_float,
@@ -703,15 +712,24 @@ natural_type(UnboxFloat, ArgWidth, Rval, Type) :-
         ArgWidth \= double_word
     then
         Type = lt_data_ptr
+    else if
+        ( Type0 = lt_int(int_type_int64)
+        ; Type0 = lt_int(int_type_uint64)
+        ),
+        UnboxInt64s = do_not_have_unboxed_int64s,
+        ArgWidth \= double_word
+    then
+        Type = lt_data_ptr
     else
         Type = Type0
     ).
 
-:- pred associate_natural_type(have_unboxed_floats::in, arg_width::in,
-    rval::in, typed_rval::out) is det.
+:- pred associate_natural_type(have_unboxed_floats::in,
+    have_unboxed_int64s::in, arg_width::in, rval::in, typed_rval::out) is det.
 
-associate_natural_type(UnboxFloat, ArgWidth, Rval, typed_rval(Rval, Type)) :-
-    natural_type(UnboxFloat, ArgWidth, Rval, Type).
+associate_natural_type(UnboxFloat, UnboxInt64s, ArgWidth, Rval,
+        typed_rval(Rval, Type)) :-
+    natural_type(UnboxFloat, UnboxInt64s, ArgWidth, Rval, Type).
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -1352,6 +1370,8 @@ remap_rval_const(Remap, Const0, Const) :-
         ; Const0 = llconst_uint16(_)
         ; Const0 = llconst_int32(_)
         ; Const0 = llconst_uint32(_)
+        ; Const0 = llconst_int64(_)
+        ; Const0 = llconst_uint64(_)
         ; Const0 = llconst_foreign(_, _)
         ; Const0 = llconst_float(_)
         ; Const0 = llconst_string(_)
diff --git a/compiler/goal_util.m b/compiler/goal_util.m
index 1aa3e98..5fe17b1 100644
--- a/compiler/goal_util.m
+++ b/compiler/goal_util.m
@@ -1200,6 +1200,8 @@ cons_id_proc_refs_acc(ConsId, !ReferredToProcs) :-
         ; ConsId = uint16_const(_)
         ; ConsId = int32_const(_)
         ; ConsId = uint32_const(_)
+        ; ConsId = int64_const(_)
+        ; ConsId = uint64_const(_)
         ; ConsId = float_const(_)
         ; ConsId = char_const(_)
         ; ConsId = string_const(_)
diff --git a/compiler/higher_order.m b/compiler/higher_order.m
index 650bab9..a1c25f4 100644
--- a/compiler/higher_order.m
+++ b/compiler/higher_order.m
@@ -921,6 +921,8 @@ is_interesting_cons_id(Params, ConsId) = IsInteresting :-
         ; ConsId = uint16_const(_)
         ; ConsId = int32_const(_)
         ; ConsId = uint32_const(_)
+        ; ConsId = int64_const(_)
+        ; ConsId = uint64_const(_)
         ; ConsId = float_const(_)
         ; ConsId = char_const(_)
         ; ConsId = string_const(_)
diff --git a/compiler/hlds_code_util.m b/compiler/hlds_code_util.m
index ba37e1c..a1b6be4 100644
--- a/compiler/hlds_code_util.m
+++ b/compiler/hlds_code_util.m
@@ -111,6 +111,12 @@ cons_id_to_tag(ModuleInfo, ConsId) = Tag:-
         ConsId = uint32_const(UInt32),
         Tag = int_tag(int_tag_uint32(UInt32))
     ;
+        ConsId = int64_const(Int64),
+        Tag = int_tag(int_tag_int64(Int64))
+    ;
+        ConsId = uint64_const(UInt64),
+        Tag = int_tag(int_tag_uint64(UInt64))
+    ;
         ConsId = float_const(Float),
         Tag = float_tag(Float)
     ;
diff --git a/compiler/hlds_data.m b/compiler/hlds_data.m
index 8c46ad7..e09aa94 100644
--- a/compiler/hlds_data.m
+++ b/compiler/hlds_data.m
@@ -711,7 +711,9 @@ cons_table_optimize(!ConsTable) :-
     ;       int_tag_int16(int16)
     ;       int_tag_uint16(uint16)
     ;       int_tag_int32(int32)
-    ;       int_tag_uint32(uint32).
+    ;       int_tag_uint32(uint32)
+    ;       int_tag_int64(int)   % XXX INT64.
+    ;       int_tag_uint64(int). % XXX INT64.
 
 :- type reserved_address
     --->    null_pointer
diff --git a/compiler/hlds_dependency_graph.m b/compiler/hlds_dependency_graph.m
index 44c89e6..11fe136 100644
--- a/compiler/hlds_dependency_graph.m
+++ b/compiler/hlds_dependency_graph.m
@@ -468,6 +468,8 @@ add_dependency_arcs_in_cons(DepGraph, WhatEdges, Caller, ConsId, !DepArcs) :-
         ; ConsId = uint16_const(_)
         ; ConsId = int32_const(_)
         ; ConsId = uint32_const(_)
+        ; ConsId = int64_const(_)
+        ; ConsId = uint64_const(_)
         ; ConsId = float_const(_)
         ; ConsId = char_const(_)
         ; ConsId = string_const(_)
diff --git a/compiler/hlds_out_pred.m b/compiler/hlds_out_pred.m
index 0e0a10d..ed0a9d1 100644
--- a/compiler/hlds_out_pred.m
+++ b/compiler/hlds_out_pred.m
@@ -1240,6 +1240,12 @@ table_trie_step_desc(TVarSet, Step) = Str :-
         Step = table_trie_step_int(int_type_uint32),
         Str = "uint32"
     ;
+        Step = table_trie_step_int(int_type_int64),
+        Str = "int64"
+    ;
+        Step = table_trie_step_int(int_type_uint64),
+        Str = "uint64"
+    ;
         Step = table_trie_step_char,
         Str = "char"
     ;
diff --git a/compiler/hlds_out_util.m b/compiler/hlds_out_util.m
index 41e28e3..a047df4 100644
--- a/compiler/hlds_out_util.m
+++ b/compiler/hlds_out_util.m
@@ -717,6 +717,18 @@ functor_cons_id_to_string(ModuleInfo, VarSet, VarNamePrint, ConsId, ArgVars)
                 size_32_bit),
             ArgVars)
     ;
+        ConsId = int64_const(Int64),
+        Str = functor_to_string(VarSet, VarNamePrint,
+            term.integer(base_10, integer(Int64), signed,
+                size_64_bit),
+            ArgVars)
+    ;
+        ConsId = uint64_const(UInt64),
+        Str = functor_to_string(VarSet, VarNamePrint,
+            term.integer(base_10, integer(UInt64), unsigned,
+                size_64_bit),
+            ArgVars)
+    ;
         ConsId = float_const(Float),
         Str = functor_to_string(VarSet, VarNamePrint,
             term.float(Float), ArgVars)
@@ -892,6 +904,14 @@ cons_id_and_vars_or_arity_to_string(VarSet, Qual, ConsId, MaybeArgVars)
         ConsId = uint32_const(UInt32),
         String = string.uint32_to_string(UInt32) ++ "u32"
     ;
+        % XXX INT64.
+        ConsId = int64_const(Int64),
+        String = string.int_to_string(Int64) ++ "i64"
+    ;
+        % XXX INT64.
+        ConsId = uint64_const(UInt64),
+        String = string.int_to_string(UInt64) ++ "u64"
+    ;
         ConsId = float_const(Float),
         String = float_to_string(Float)
     ;
diff --git a/compiler/implementation_defined_literals.m b/compiler/implementation_defined_literals.m
index 3d1ffd2..ed1d80f 100644
--- a/compiler/implementation_defined_literals.m
+++ b/compiler/implementation_defined_literals.m
@@ -110,6 +110,8 @@ subst_literals_in_goal(Info, Goal0, Goal) :-
                 ; ConsId = uint16_const(_)
                 ; ConsId = int32_const(_)
                 ; ConsId = uint32_const(_)
+                ; ConsId = int64_const(_)
+                ; ConsId = uint64_const(_)
                 ; ConsId = float_const(_)
                 ; ConsId = char_const(_)
                 ; ConsId = string_const(_)
diff --git a/compiler/inst_check.m b/compiler/inst_check.m
index fcc924b..a5ddba7 100644
--- a/compiler/inst_check.m
+++ b/compiler/inst_check.m
@@ -288,6 +288,18 @@ check_inst_defn_has_matching_type(TypeTable, FunctorsToTypesMap, InstId,
                     ForTypeCtor = uint32_type_ctor,
                     MaybeForTypeKind = yes(ftk_int(int_type_uint32))
                 else if
+                    sym_name_for_builtin_type(ForTypeCtorName, "int64"),
+                    ForTypeCtorArity = 0
+                then
+                    ForTypeCtor = int64_type_ctor,
+                    MaybeForTypeKind = yes(ftk_int(int_type_int64))
+                else if
+                    sym_name_for_builtin_type(ForTypeCtorName, "uint64"),
+                    ForTypeCtorArity = 0
+                then
+                    ForTypeCtor = uint64_type_ctor,
+                    MaybeForTypeKind = yes(ftk_int(int_type_uint64))
+                else if
                     sym_name_for_builtin_type(ForTypeCtorName, "float"),
                     ForTypeCtorArity = 0
                 then
@@ -437,6 +449,12 @@ type_defn_or_builtin_to_type_ctor(TypeDefnOrBuiltin, TypeCtor) :-
             BuiltinType = builtin_type_int(int_type_uint32),
             TypeCtor = type_ctor(unqualified("uint32"), 0)
         ;
+            BuiltinType = builtin_type_int(int_type_int64),
+            TypeCtor = type_ctor(unqualified("int64"), 0)
+        ;
+            BuiltinType = builtin_type_int(int_type_uint64),
+            TypeCtor = type_ctor(unqualified("uint64"), 0)
+        ;
             BuiltinType = builtin_type_float,
             TypeCtor = type_ctor(unqualified("float"), 0)
         ;
@@ -597,6 +615,20 @@ check_for_type_bound_insts(ForTypeKind, [BoundInst | BoundInsts],
             !:Mismatches = cord.snoc(!.Mismatches, simple_miss(ConsId))
         )
     ;
+        ConsId = int64_const(_),
+        ( if ForTypeKind = ftk_int(int_type_int64) then
+            true
+        else
+            !:Mismatches = cord.snoc(!.Mismatches, simple_miss(ConsId))
+        )
+    ;
+        ConsId = uint64_const(_),
+        ( if ForTypeKind = ftk_int(int_type_uint64) then
+            true
+        else
+            !:Mismatches = cord.snoc(!.Mismatches, simple_miss(ConsId))
+        )
+    ;
         ConsId = float_const(_),
         (
             ForTypeKind = ftk_float
@@ -793,6 +825,12 @@ get_possible_types_for_bound_inst(FunctorsToTypesMap, BoundInst, MaybeTypes) :-
         ;
             ConsId = uint32_const(_),
             IntType = int_type_uint32
+        ;
+            ConsId = int64_const(_),
+            IntType = int_type_int64
+        ;
+            ConsId = uint64_const(_),
+            IntType = int_type_uint64
         ),
         MaybeTypes = yes([type_builtin(builtin_type_int(IntType))])
     ;
@@ -918,6 +956,12 @@ maybe_issue_type_match_error(InstId, InstDefn, ForTypeKind, IFTC, Mismatches,
             ForTypeKind = ftk_int(int_type_uint32),
             ForTypeCtor = uint32_type_ctor
         ;
+            ForTypeKind = ftk_int(int_type_int64),
+            ForTypeCtor = int64_type_ctor
+        ;
+            ForTypeKind = ftk_int(int_type_uint64),
+            ForTypeCtor = uint64_type_ctor
+        ;
             ForTypeKind = ftk_float,
             ForTypeCtor = float_type_ctor
         ;
@@ -1320,6 +1364,20 @@ find_mismatches_from_builtin(ExpectedBuiltinType, CurNum,
             record_mismatch(CurNum, BoundInst, !NumMismatches, !PiecesCord)
         )
     ;
+        ExpectedBuiltinType = builtin_type_int(int_type_int64),
+        ( if ConsId = int64_const(_) then
+            true
+        else
+            record_mismatch(CurNum, BoundInst, !NumMismatches, !PiecesCord)
+        )
+    ;
+        ExpectedBuiltinType = builtin_type_int(int_type_uint64),
+        ( if ConsId = uint64_const(_) then
+            true
+        else
+            record_mismatch(CurNum, BoundInst, !NumMismatches, !PiecesCord)
+        )
+    ;
         ExpectedBuiltinType = builtin_type_float,
         ( if ConsId = float_const(_) then
             true
@@ -1499,6 +1557,12 @@ type_defn_or_builtin_to_string(TypeDefnOrBuiltin) = Str :-
             BuiltinType = builtin_type_int(int_type_uint32),
             Str = "uint32"
         ;
+            BuiltinType = builtin_type_int(int_type_int64),
+            Str = "int64"
+        ;
+            BuiltinType = builtin_type_int(int_type_uint64),
+            Str = "uint64"
+        ;
             BuiltinType = builtin_type_float,
             Str = "float"
         ;
diff --git a/compiler/jumpopt.m b/compiler/jumpopt.m
index 1fcc9e1..7f21abb 100644
--- a/compiler/jumpopt.m
+++ b/compiler/jumpopt.m
@@ -1165,6 +1165,8 @@ short_circuit_labels_const(InstrMap, RvalConst0, RvalConst) :-
         ; RvalConst0 = llconst_uint16(_U16)
         ; RvalConst0 = llconst_int32(_I32)
         ; RvalConst0 = llconst_uint32(_U32)
+        ; RvalConst0 = llconst_int64(_I64)
+        ; RvalConst0 = llconst_uint64(_U64)
         ; RvalConst0 = llconst_foreign(_V, _T)
         ; RvalConst0 = llconst_float(_F)
         ; RvalConst0 = llconst_string(_S)
diff --git a/compiler/llds.m b/compiler/llds.m
index 16956bc..0557674 100644
--- a/compiler/llds.m
+++ b/compiler/llds.m
@@ -1215,6 +1215,9 @@
     ;       llconst_int32(int32)
     ;       llconst_uint32(uint32)
 
+    ;       llconst_int64(int)   % XXX INT64
+    ;       llconst_uint64(int)  % XXX INT64
+
     ;       llconst_foreign(string, llds_type)
             % A constant in the target language.
             % It may be a #defined constant in C which is why
@@ -1496,6 +1499,10 @@
     --->    have_static_code_addresses
     ;       do_not_have_static_code_addresses.
 
+:- type have_unboxed_int64s
+    --->    have_unboxed_int64s
+    ;       do_not_have_unboxed_int64s.
+
 :- type exprn_opts
     --->    exprn_opts(
                 non_local_gotos         :: have_non_local_gotos,
@@ -1505,7 +1512,8 @@
                 det_stack_float_width   :: stack_slot_width,
                 static_ground_cells     :: have_static_ground_cells,
                 static_ground_floats    :: have_static_ground_floats,
-                static_code_addresses   :: have_static_code_addresses
+                static_code_addresses   :: have_static_code_addresses,
+                unboxed_int64s          :: have_unboxed_int64s
             ).
 
 :- func get_nonlocal_gotos(exprn_opts) = have_non_local_gotos.
@@ -1516,6 +1524,7 @@
 :- func get_static_ground_cells(exprn_opts) = have_static_ground_cells.
 :- func get_static_ground_floats(exprn_opts) = have_static_ground_floats.
 :- func get_static_code_addresses(exprn_opts) = have_static_code_addresses.
+:- func get_unboxed_int64s(exprn_opts) = have_unboxed_int64s.
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -1688,6 +1697,8 @@ const_type(llconst_int16(_), lt_int(int_type_int16)).
 const_type(llconst_uint16(_), lt_int(int_type_uint16)).
 const_type(llconst_int32(_), lt_int(int_type_int32)).
 const_type(llconst_uint32(_), lt_int(int_type_uint32)).
+const_type(llconst_int64(_), lt_int(int_type_int64)).
+const_type(llconst_uint64(_), lt_int(int_type_uint64)).
 const_type(llconst_foreign(_, Type), Type).
 const_type(llconst_float(_), lt_float).
 const_type(llconst_string(_), lt_string).
@@ -1790,6 +1801,7 @@ get_float_registers(ExprnOpts) = ExprnOpts ^ float_registers.
 get_det_stack_float_width(ExprnOpts) = ExprnOpts ^ det_stack_float_width.
 get_static_ground_floats(ExprnOpts) = ExprnOpts ^ static_ground_floats.
 get_static_code_addresses(ExprnOpts) = ExprnOpts ^ static_code_addresses.
+get_unboxed_int64s(ExprnOpts) = ExprnOpts ^ unboxed_int64s.
 
 %-----------------------------------------------------------------------------%
 :- end_module ll_backend.llds.
diff --git a/compiler/llds_out_data.m b/compiler/llds_out_data.m
index 0e83423..546a096 100644
--- a/compiler/llds_out_data.m
+++ b/compiler/llds_out_data.m
@@ -593,6 +593,10 @@ output_llds_type(lt_int(int_type_int32), !IO) :-
     io.write_string("int32_t", !IO).
 output_llds_type(lt_int(int_type_uint32), !IO) :-
     io.write_string("uint32_t", !IO).
+output_llds_type(lt_int(int_type_int64), !IO) :-
+    io.write_string("int64_t", !IO).
+output_llds_type(lt_int(int_type_uint64), !IO) :-
+    io.write_string("uint64_t", !IO).
 output_llds_type(lt_float, !IO) :-
     io.write_string("MR_Float", !IO).
 output_llds_type(lt_word, !IO) :-
@@ -1236,6 +1240,12 @@ output_rval_const(Info, Const, !IO) :-
         Const = llconst_uint32(N),
         c_util.output_uint32_expr_cur_stream(N, !IO)
     ;
+        Const = llconst_int64(N),
+        c_util.output_int64_expr_cur_stream(N, !IO)
+    ;
+        Const = llconst_uint64(N),
+        c_util.output_uint64_expr_cur_stream(N, !IO)
+    ;
         Const = llconst_foreign(Value, Type),
         io.write_char('(', !IO),
         output_llds_type_cast(Type, !IO),
@@ -1388,6 +1398,12 @@ builtin_type_to_type_ctor_addr(Name, Macro) :-
         Name = "uint32",
         Macro = "MR_UINT32_CTOR_ADDR"
     ;
+        Name = "int64",
+        Macro = "MR_INT64_CTOR_ADDR"
+    ;
+        Name = "uint64",
+        Macro = "MR_UINT64_CTOR_ADDR"
+    ;
         Name = "float",
         Macro = "MR_FLOAT_CTOR_ADDR"
     ;
diff --git a/compiler/llds_out_instr.m b/compiler/llds_out_instr.m
index e35511f..2ecb6e7 100644
--- a/compiler/llds_out_instr.m
+++ b/compiler/llds_out_instr.m
@@ -2089,10 +2089,49 @@ output_foreign_proc_output(Info, Output, !IO) :-
                     io.write_string("(MR_UnsignedChar) ", !IO),
                     io.write_string(VarName, !IO)
                 ;
-                    BuiltinType = builtin_type_int(_),
-                    output_lval_as_word(Info, Lval, !IO),
-                    io.write_string(" = ", !IO),
-                    io.write_string(VarName, !IO)
+                    BuiltinType = builtin_type_int(IntType),
+                    (
+                        ( IntType = int_type_int
+                        ; IntType = int_type_uint
+                        ; IntType = int_type_int8
+                        ; IntType = int_type_uint8
+                        ; IntType = int_type_int16
+                        ; IntType = int_type_uint16
+                        ; IntType = int_type_int32
+                        ; IntType = int_type_uint32
+                        ),
+                        output_lval_as_word(Info, Lval, !IO),
+                        io.write_string(" = ", !IO),
+                        io.write_string(VarName, !IO)
+                    ;
+                        IntType = int_type_int64,
+                        llds.lval_type(Lval, ActualType),
+                        ( if ActualType = lt_int(int_type_int64) then
+                            output_lval(Info, Lval, !IO),
+                            io.write_string(" = ", !IO),
+                            io.write_string(VarName, !IO)
+                        else
+                            output_lval_as_word(Info, Lval, !IO),
+                            io.write_string(" = ", !IO),
+                            io.write_string("MR_int64_to_word(", !IO),
+                            io.write_string(VarName, !IO),
+                            io.write_string(")", !IO)
+                        )
+                    ;
+                        IntType = int_type_uint64,
+                        llds.lval_type(Lval, ActualType),
+                        ( if ActualType = lt_int(int_type_uint64) then
+                            output_lval(Info, Lval, !IO),
+                            io.write_string(" = ", !IO),
+                            io.write_string(VarName, !IO)
+                        else
+                            output_lval_as_word(Info, Lval, !IO),
+                            io.write_string(" = ", !IO),
+                            io.write_string("MR_uint64_to_word(", !IO),
+                            io.write_string(VarName, !IO),
+                            io.write_string(")", !IO)
+                        )
+                    )
                 )
             else
                 output_lval_as_word(Info, Lval, !IO),
diff --git a/compiler/lookup_switch.m b/compiler/lookup_switch.m
index 01c0f42..462ff4b 100644
--- a/compiler/lookup_switch.m
+++ b/compiler/lookup_switch.m
@@ -212,11 +212,13 @@ is_lookup_switch(BranchStart, GetTag, TaggedCases, GoalInfo, StoreMap,
     ),
     get_exprn_opts(!.CI, ExprnOpts),
     UnboxFloats = get_unboxed_floats(ExprnOpts),
+    UnboxInt64s = get_unboxed_int64s(ExprnOpts),
     map.to_assoc_list(CaseSolnMap, CaseSolns),
     % This generates CaseValues in reverse order of index, but given that
     % we only use CaseValues to find out the right OutLLDSTypes, this is OK.
     project_solns_to_rval_lists(CaseSolns, [], CaseValues),
-    find_general_llds_types(UnboxFloats, OutTypes, CaseValues, OutLLDSTypes),
+    find_general_llds_types(UnboxFloats, UnboxInt64s, OutTypes, CaseValues,
+        OutLLDSTypes),
     LookupSwitchInfo = lookup_switch_info(CaseConsts, OutVars, OutLLDSTypes,
         Liveness).
 
@@ -960,6 +962,10 @@ default_value_for_type(lt_int(int_type_int16)) = const(llconst_int16(0i16)).
 default_value_for_type(lt_int(int_type_uint16)) = const(llconst_uint16(0u16)).
 default_value_for_type(lt_int(int_type_int32)) = const(llconst_int32(0i32)).
 default_value_for_type(lt_int(int_type_uint32)) = const(llconst_uint32(0u32)).
+% XXX INT64.
+default_value_for_type(lt_int(int_type_int64)) = const(llconst_int64(0)).
+% XXX INT64.
+default_value_for_type(lt_int(int_type_uint64)) = const(llconst_uint64(0)).
 default_value_for_type(lt_float) = const(llconst_float(0.0)).
 default_value_for_type(lt_string) = const(llconst_string("")).
 default_value_for_type(lt_data_ptr) = const(llconst_int(0)).
diff --git a/compiler/mercury_compile_llds_back_end.m b/compiler/mercury_compile_llds_back_end.m
index 04477aa..b9d137b 100644
--- a/compiler/mercury_compile_llds_back_end.m
+++ b/compiler/mercury_compile_llds_back_end.m
@@ -119,8 +119,16 @@ llds_backend_pass(!HLDS, !:GlobalData, LLDS, !DumpInfo, !IO) :-
         OptUnboxFloat = no,
         UnboxFloats = do_not_have_unboxed_floats
     ),
+    globals.lookup_bool_option(Globals, unboxed_int64s, OptUnboxInt64s),
+    (
+        OptUnboxInt64s = yes,
+        UnboxInt64s = have_unboxed_int64s
+    ;
+        OptUnboxInt64s = no,
+        UnboxInt64s = do_not_have_unboxed_int64s
+    ),
     StaticCellInfo0 = init_static_cell_info(ModuleName, UnboxFloats,
-        DoCommonData),
+        DoCommonData, UnboxInt64s),
     module_info_get_ts_rev_string_table(!.HLDS, TSStringTableSize,
         TSRevStringTable),
     global_data_init(StaticCellInfo0, TSStringTableSize, TSRevStringTable,
diff --git a/compiler/mercury_to_mercury.m b/compiler/mercury_to_mercury.m
index a88aeb0..5047a3b 100644
--- a/compiler/mercury_to_mercury.m
+++ b/compiler/mercury_to_mercury.m
@@ -285,6 +285,12 @@ mercury_format_cons_id(NeedsBrackets, ConsId, !U) :-
         ConsId = uint32_const(UInt32),
         add_uint32(UInt32, !U)
     ;
+        ConsId = int64_const(Int64),
+        add_int(Int64, !U) % XXX INT64
+    ;
+        ConsId = uint64_const(UInt64),
+        add_int(UInt64, !U) % XXX INT64
+    ;
         ConsId = float_const(Float),
         add_float(Float, !U)
     ;
diff --git a/compiler/ml_call_gen.m b/compiler/ml_call_gen.m
index caee3d1..2e85d08 100644
--- a/compiler/ml_call_gen.m
+++ b/compiler/ml_call_gen.m
@@ -873,6 +873,8 @@ ml_gen_simple_expr(int16_const(Int16)) = ml_const(mlconst_int16(Int16)).
 ml_gen_simple_expr(uint16_const(UInt16)) = ml_const(mlconst_uint16(UInt16)).
 ml_gen_simple_expr(int32_const(Int32)) = ml_const(mlconst_int32(Int32)).
 ml_gen_simple_expr(uint32_const(UInt32)) = ml_const(mlconst_uint32(UInt32)).
+ml_gen_simple_expr(int64_const(Int64)) = ml_const(mlconst_int64(Int64)).
+ml_gen_simple_expr(uint64_const(UInt64)) = ml_const(mlconst_uint64(UInt64)).
 ml_gen_simple_expr(float_const(Float)) = ml_const(mlconst_float(Float)).
 ml_gen_simple_expr(unary(Op, Expr)) =
     ml_unop(std_unop(Op), ml_gen_simple_expr(Expr)).
@@ -1012,6 +1014,8 @@ may_const_yield_dangling_stack_ref(Const) = MayYieldDanglingStackRef :-
         ; Const = mlconst_uint16(_)
         ; Const = mlconst_int32(_)
         ; Const = mlconst_uint32(_)
+        ; Const = mlconst_int64(_)
+        ; Const = mlconst_uint64(_)
         ; Const = mlconst_enum(_, _)
         ; Const = mlconst_char(_)
         ; Const = mlconst_foreign(_, _, _)
diff --git a/compiler/ml_code_util.m b/compiler/ml_code_util.m
index 663d859..bfb9a60 100644
--- a/compiler/ml_code_util.m
+++ b/compiler/ml_code_util.m
@@ -707,6 +707,12 @@ ml_int_tag_to_rval_const(IntTag, MerType, MLDS_Type) = Rval :-
     ;
         IntTag = int_tag_uint32(UInt32),
         Rval = ml_const(mlconst_uint32(UInt32))
+    ;
+        IntTag = int_tag_int64(Int64),
+        Rval = ml_const(mlconst_int64(Int64))
+    ;
+        IntTag = int_tag_uint64(UInt64),
+        Rval = ml_const(mlconst_uint64(UInt64))
     ).
 
 %---------------------------------------------------------------------------%
diff --git a/compiler/ml_global_data.m b/compiler/ml_global_data.m
index 84cf30c..e1e947f 100644
--- a/compiler/ml_global_data.m
+++ b/compiler/ml_global_data.m
@@ -46,6 +46,10 @@
     --->    have_unboxed_floats
     ;       do_not_have_unboxed_floats.
 
+:- type have_unboxed_int64s
+    --->    have_unboxed_int64s
+    ;       do_not_have_unboxed_int64s.
+
 :- type ml_scalar_cell_map ==
     map(ml_scalar_common_type_num, ml_scalar_cell_group).
 
@@ -84,12 +88,15 @@
     % Initialize the ml_global_data structure to a value that represents
     % no global data structures known yet.
     %
-:- func ml_global_data_init(use_common_cells, have_unboxed_floats) =
-    ml_global_data.
+:- func ml_global_data_init(use_common_cells, have_unboxed_floats,
+    have_unboxed_int64s) = ml_global_data.
 
 :- func ml_global_data_have_unboxed_floats(ml_global_data) =
     have_unboxed_floats.
 
+:- func ml_global_data_have_unboxed_int64s(ml_global_data) =
+    have_unboxed_int64s.
+
     % ml_global_data_get_all_global_defns(GlobalData,
     %     ScalarCellGroupMap, VectorCellGroupMap, AllocIds,
     %     RttiDefns, CellDefns, ClosureWrapperFuncDefns):
@@ -237,6 +244,7 @@
                 mgd_pdup_rval_type_map          :: ml_rtti_rval_type_map,
                 mgd_use_common_cells            :: use_common_cells,
                 mgd_have_unboxed_floats         :: have_unboxed_floats,
+                mgd_have_unboxed_int64s         :: have_unboxed_int64s,
                 mgd_const_counter               :: counter,
 
                 mgd_cell_defns                  :: cord(mlds_global_var_defn),
@@ -257,20 +265,24 @@
 
 %---------------------------------------------------------------------------%
 
-ml_global_data_init(UseCommonCells, HaveUnboxedFloats) = GlobalData :-
+ml_global_data_init(UseCommonCells, HaveUnboxedFloats, HaveUnboxedInt64s) =
+        GlobalData :-
     GlobalData = ml_global_data(map.init, UseCommonCells, HaveUnboxedFloats,
-        counter.init(1), cord.init, cord.init, cord.init,
+        HaveUnboxedInt64s, counter.init(1), cord.init, cord.init, cord.init,
         counter.init(1), map.init, map.init, map.init, map.init,
         counter.init(0), bimap.init).
 
 ml_global_data_have_unboxed_floats(GlobalData) =
     GlobalData ^ mgd_have_unboxed_floats.
 
+ml_global_data_have_unboxed_int64s(GlobalData) =
+    GlobalData ^ mgd_have_unboxed_int64s.
+
 ml_global_data_get_all_global_defns(GlobalData,
         ScalarCellGroupMap, VectorCellGroupMap, AllocIds,
         RttiDefns, CellDefns, ClosureWrapperFuncDefns) :-
     GlobalData = ml_global_data(_PDupRvalTypeMap, _UseCommonCells,
-        _HaveUnboxedFloats, _ConstCounter,
+        _HaveUnboxedFloats, _HaveUnboxedInt64s, _ConstCounter,
         CellDefnsCord, RttiDefnsCord, ClosureWrapperFuncDefnsCord,
         _TypeNumCounter,
         _ScalarTypeNumMap, ScalarCellGroupMap,
@@ -765,6 +777,8 @@ cons_id_to_alloc_site_string(ConsId) = TypeStr :-
         ; ConsId = uint16_const(_)
         ; ConsId = int32_const(_)
         ; ConsId = uint32_const(_)
+        ; ConsId = int64_const(_)
+        ; ConsId = uint64_const(_)
         ; ConsId = float_const(_)
         ; ConsId = char_const(_)
         ; ConsId = string_const(_)
diff --git a/compiler/ml_rename_classes.m b/compiler/ml_rename_classes.m
index 4108808..3b36b42 100644
--- a/compiler/ml_rename_classes.m
+++ b/compiler/ml_rename_classes.m
@@ -461,6 +461,8 @@ rename_class_names_in_rval_const(Renaming, !Const) :-
         ; !.Const = mlconst_uint16(_)
         ; !.Const = mlconst_int32(_)
         ; !.Const = mlconst_uint32(_)
+        ; !.Const = mlconst_int64(_)
+        ; !.Const = mlconst_uint64(_)
         ; !.Const = mlconst_char(_)
         ; !.Const = mlconst_enum(_, _)
         ; !.Const = mlconst_float(_)
diff --git a/compiler/ml_top_gen.m b/compiler/ml_top_gen.m
index e4136e3..5d24c3e 100644
--- a/compiler/ml_top_gen.m
+++ b/compiler/ml_top_gen.m
@@ -188,7 +188,16 @@ ml_gen_init_global_data(ModuleInfo, Target, GlobalData) :-
         UnboxedFloats = no,
         HaveUnboxedFloats = do_not_have_unboxed_floats
     ),
-    GlobalData = ml_global_data_init(UseCommonCells, HaveUnboxedFloats).
+    globals.lookup_bool_option(Globals, unboxed_int64s, UnboxedInt64s),
+    (
+        UnboxedInt64s = yes,
+        HaveUnboxedInt64s = have_unboxed_int64s
+    ;
+        UnboxedInt64s = no,
+        HaveUnboxedInt64s = do_not_have_unboxed_int64s
+    ),
+    GlobalData = ml_global_data_init(UseCommonCells, HaveUnboxedFloats,
+        HaveUnboxedInt64s).
 
 %---------------------------------------------------------------------------%
 %
diff --git a/compiler/ml_type_gen.m b/compiler/ml_type_gen.m
index bf47202..9ca992a 100644
--- a/compiler/ml_type_gen.m
+++ b/compiler/ml_type_gen.m
@@ -346,6 +346,8 @@ ml_gen_hld_enum_constant(Context, TypeCtor, ConsTagValues, MLDS_Type, Ctor)
             ; IntTag = int_tag_uint16(_)
             ; IntTag = int_tag_int32(_)
             ; IntTag = int_tag_uint32(_)
+            ; IntTag = int_tag_int64(_)
+            ; IntTag = int_tag_uint64(_)
             ),
             unexpected($pred, "enum constant needs int tag")
         )
@@ -1200,6 +1202,8 @@ generate_foreign_enum_constant(TypeCtor, Mapping, TagValues, MLDS_Type, Ctor,
             ; IntTag = int_tag_uint16(_)
             ; IntTag = int_tag_int32(_)
             ; IntTag = int_tag_uint32(_)
+            ; IntTag = int_tag_int64(_)
+            ; IntTag = int_tag_uint64(_)
             ),
             unexpected($pred,
                 "enum constant requires an int or foreign tag")
diff --git a/compiler/ml_unify_gen.m b/compiler/ml_unify_gen.m
index 2e0f414..f217fdf 100644
--- a/compiler/ml_unify_gen.m
+++ b/compiler/ml_unify_gen.m
@@ -2261,6 +2261,14 @@ ml_gen_int_tag_test_rval(IntTag, Type, ModuleInfo, Rval) = TagTestRval :-
         IntTag = int_tag_uint32(UInt32),
         TagTestRval = ml_binop(eq(int_type_uint32), Rval,
             ml_const(mlconst_uint32(UInt32)))
+    ;
+        IntTag = int_tag_int64(Int64),
+        TagTestRval = ml_binop(eq(int_type_int64), Rval,
+            ml_const(mlconst_int64(Int64)))
+    ;
+        IntTag = int_tag_uint64(UInt64),
+        TagTestRval = ml_binop(eq(int_type_uint64), Rval,
+            ml_const(mlconst_uint64(UInt64)))
     ).
 
 ml_gen_secondary_tag_rval(ModuleInfo, Target, PrimaryTagVal, VarType, Rval) =
@@ -3200,6 +3208,12 @@ int_tag_to_mlds_rval_const(Type, MLDS_Type, IntTag) = Const :-
     ;
         IntTag = int_tag_uint32(UInt32),
         Const = mlconst_uint32(UInt32)
+    ;
+        IntTag = int_tag_int64(Int64),
+        Const = mlconst_int64(Int64)
+    ;
+        IntTag = int_tag_uint64(UInt64),
+        Const = mlconst_uint64(UInt64)
     ).
 
 %---------------------------------------------------------------------------%
diff --git a/compiler/ml_util.m b/compiler/ml_util.m
index 2a5025e..0016cf6 100644
--- a/compiler/ml_util.m
+++ b/compiler/ml_util.m
@@ -758,6 +758,8 @@ rval_contains_var(Rval, SearchVarName) = ContainsVar :-
             ; Const = mlconst_uint16(_)
             ; Const = mlconst_int32(_)
             ; Const = mlconst_uint32(_)
+            ; Const = mlconst_int64(_)
+            ; Const = mlconst_uint64(_)
             ; Const = mlconst_enum(_, _)
             ; Const = mlconst_char(_)
             ; Const = mlconst_float(_)
diff --git a/compiler/mlds.m b/compiler/mlds.m
index a4a0ad3..b7d324a 100644
--- a/compiler/mlds.m
+++ b/compiler/mlds.m
@@ -1808,6 +1808,8 @@
     ;       mlconst_uint16(uint16)
     ;       mlconst_int32(int32)
     ;       mlconst_uint32(uint32)
+    ;       mlconst_int64(int)  % XXX INT64.
+    ;       mlconst_uint64(int) % XXX INT64.
     ;       mlconst_enum(int, mlds_type)
     ;       mlconst_char(int)
     ;       mlconst_float(float)
diff --git a/compiler/mlds_to_c.m b/compiler/mlds_to_c.m
index e7ff816..b83d9bb 100644
--- a/compiler/mlds_to_c.m
+++ b/compiler/mlds_to_c.m
@@ -3112,6 +3112,12 @@ mlds_output_mercury_type_prefix(Opts, Type, CtorCat, !IO) :-
         CtorCat = ctor_cat_builtin(cat_builtin_int(int_type_uint32)),
         io.write_string("uint32_t", !IO)
     ;
+        CtorCat = ctor_cat_builtin(cat_builtin_int(int_type_int64)),
+        io.write_string("int64_t", !IO)
+    ;
+        CtorCat = ctor_cat_builtin(cat_builtin_int(int_type_uint64)),
+        io.write_string("uint64_t", !IO)
+    ;
         CtorCat = ctor_cat_builtin(cat_builtin_string),
         io.write_string("MR_String", !IO)
     ;
@@ -4872,6 +4878,20 @@ mlds_output_boxed_rval(Opts, Type, Expr, !IO) :-
             io.write_string(")", !IO)
         )
     else if
+        Type = mercury_type(builtin_type(BuiltinType), _,  _),
+        BuiltinType = builtin_type_int(int_type_int64)
+    then
+        io.write_string("MR_box_int64(", !IO),
+        mlds_output_rval(Opts, Expr, !IO),
+        io.write_string(")", !IO)
+    else if
+        Type = mercury_type(builtin_type(BuiltinType), _, _),
+        BuiltinType = builtin_type_int(int_type_uint64)
+    then
+        io.write_string("MR_box_uint64", !IO),
+        mlds_output_rval(Opts, Expr, !IO),
+        io.write_string(")", !IO)
+    else if
         type_is_smaller_than_word(Type)
     then
         % We cast first to MR_Word, and then to MR_Box.
@@ -4972,6 +4992,8 @@ is_an_address(Rval) = IsAddr :-
             ; Const = mlconst_uint16(_)
             ; Const = mlconst_int32(_)
             ; Const = mlconst_uint32(_)
+            ; Const = mlconst_int64(_)
+            ; Const = mlconst_uint64(_)
             ; Const = mlconst_float(_)
             ; Const = mlconst_foreign(_, _, _)
             ),
@@ -4992,6 +5014,20 @@ mlds_output_unboxed_rval(Opts, Type, Expr, !IO) :-
         mlds_output_rval(Opts, Expr, !IO),
         io.write_string(")", !IO)
     else if
+        Type = mercury_type(builtin_type(BuiltinType), _, _),
+        BuiltinType = builtin_type_int(int_type_int64)
+    then
+        io.write_string("MR_unbox_int64(", !IO),
+        mlds_output_rval(Opts, Expr, !IO),
+        io.write_string(")", !IO)
+    else if
+        Type = mercury_type(builtin_type(BuiltinType), _, _),
+        BuiltinType = builtin_type_int(int_type_uint64)
+    then
+        io.write_string("MR_unbox_uint64(", !IO),
+        mlds_output_rval(Opts, Expr, !IO),
+        io.write_string(")", !IO)
+    else if
         type_is_smaller_than_word(Type)
     then
         % We cast first to MR_Word, and then to the desired type.
@@ -5216,6 +5252,12 @@ mlds_output_rval_const(_Opts, Const, !IO) :-
         Const = mlconst_uint32(N),
         c_util.output_uint32_expr_cur_stream(N, !IO)
     ;
+        Const = mlconst_int64(N),
+        c_util.output_int64_expr_cur_stream(N, !IO)
+    ;
+        Const = mlconst_uint64(N),
+        c_util.output_uint64_expr_cur_stream(N, !IO)
+    ;
         Const = mlconst_char(C),
         io.write_string("(MR_Char) ", !IO),
         io.write_int(C, !IO)
diff --git a/compiler/mlds_to_cs.m b/compiler/mlds_to_cs.m
index 75f88a1..38c6446 100644
--- a/compiler/mlds_to_cs.m
+++ b/compiler/mlds_to_cs.m
@@ -1093,6 +1093,12 @@ get_type_initializer(Info, Type) = Initializer :-
             ),
             Initializer = "0U"
         ;
+            CtorCat = ctor_cat_builtin(cat_builtin_int(int_type_int64)),
+            Initializer = "0L"
+        ;
+            CtorCat = ctor_cat_builtin(cat_builtin_int(int_type_uint64)),
+            Initializer = "0UL"
+        ;
             CtorCat = ctor_cat_builtin(cat_builtin_char),
             Initializer = "'\\u0000'"
         ;
@@ -1992,6 +1998,8 @@ int_type_to_csharp_type(int_type_int16) = "short".
 int_type_to_csharp_type(int_type_uint16) = "ushort".
 int_type_to_csharp_type(int_type_int32) = "int".
 int_type_to_csharp_type(int_type_uint32) = "uint".
+int_type_to_csharp_type(int_type_int64) = "long".
+int_type_to_csharp_type(int_type_uint64) = "ulong".
 
 :- pred mercury_user_type_to_string_csharp(csharp_out_info::in, mer_type::in,
     type_ctor_category::in, string::out, list(int)::out) is det.
@@ -3406,6 +3414,8 @@ output_std_unop_for_csharp(Info, UnaryOp, Expr, !IO) :-
         ; UnaryOp = bitwise_complement(int_type_uint), UnaryOpStr = "~"
         ; UnaryOp = bitwise_complement(int_type_int32), UnaryOpStr = "~"
         ; UnaryOp = bitwise_complement(int_type_uint32), UnaryOpStr = "~"
+        ; UnaryOp = bitwise_complement(int_type_int64), UnaryOpStr = "~"
+        ; UnaryOp = bitwise_complement(int_type_uint64), UnaryOpStr = "~"
         ; UnaryOp = logical_not, UnaryOpStr = "!"
         ; UnaryOp = hash_string,  UnaryOpStr = "mercury.String.hash_1_f_0"
         ; UnaryOp = hash_string2, UnaryOpStr = "mercury.String.hash2_1_f_0"
@@ -3538,6 +3548,26 @@ output_binop_for_csharp(Info, Op, X, Y, !IO) :-
         ; Op = bitwise_xor(int_type_uint32)
         ; Op = unchecked_left_shift(int_type_uint32)
         ; Op = unchecked_right_shift(int_type_uint32)
+        ; Op = int_add(int_type_int64)
+        ; Op = int_sub(int_type_int64)
+        ; Op = int_mul(int_type_int64)
+        ; Op = int_div(int_type_int64)
+        ; Op = int_mod(int_type_int64)
+        ; Op = bitwise_and(int_type_int64)
+        ; Op = bitwise_or(int_type_int64)
+        ; Op = bitwise_xor(int_type_int64)
+        ; Op = unchecked_left_shift(int_type_int64)
+        ; Op = unchecked_right_shift(int_type_int64)
+        ; Op = int_add(int_type_uint64)
+        ; Op = int_sub(int_type_uint64)
+        ; Op = int_mul(int_type_uint64)
+        ; Op = int_div(int_type_uint64)
+        ; Op = int_mod(int_type_uint64)
+        ; Op = bitwise_and(int_type_uint64)
+        ; Op = bitwise_or(int_type_uint64)
+        ; Op = bitwise_xor(int_type_uint64)
+        ; Op = unchecked_left_shift(int_type_uint64)
+        ; Op = unchecked_right_shift(int_type_uint64)
         ; Op = float_plus
         ; Op = float_minus
         ; Op = float_times
@@ -3741,6 +3771,12 @@ output_rval_const_for_csharp(Info, Const, !IO) :-
         Const = mlconst_uint32(N),
         output_uint32_const_for_csharp(N, !IO)
     ;
+        Const = mlconst_int64(N),
+        output_int64_const_for_csharp(N, !IO)
+    ;
+        Const = mlconst_uint64(N),
+        output_uint64_const_for_csharp(N, !IO)
+    ;
         Const = mlconst_char(N),
         io.write_string("( ", !IO),
         output_int_const_for_csharp(N, !IO),
@@ -3890,6 +3926,18 @@ output_uint32_const_for_csharp(U32, !IO) :-
     io.write_uint32(U32, !IO),
     io.write_string("U", !IO).
 
+:- pred output_int64_const_for_csharp(int::in, io::di, io::uo) is det.
+
+output_int64_const_for_csharp(I64, !IO) :-
+    io.write_int(I64, !IO),
+    io.write_string("L", !IO).
+
+:- pred output_uint64_const_for_csharp(int::in, io::di, io::uo) is det.
+
+output_uint64_const_for_csharp(U64, !IO) :-
+    io.write_int(U64, !IO),
+    io.write_string("UL", !IO).
+
 %---------------------------------------------------------------------------%
 
 :- pred mlds_output_code_addr_for_csharp(csharp_out_info::in,
diff --git a/compiler/mlds_to_java.m b/compiler/mlds_to_java.m
index 2146183..53a7855 100644
--- a/compiler/mlds_to_java.m
+++ b/compiler/mlds_to_java.m
@@ -2666,6 +2666,12 @@ mercury_type_to_string_for_java(Info, Type, CtorCat, String, ArrayDims) :-
         String = "short",
         ArrayDims = []
     ;
+        ( CtorCat = ctor_cat_builtin(cat_builtin_int(int_type_int64))
+        ; CtorCat = ctor_cat_builtin(cat_builtin_int(int_type_uint64))
+        ),
+        String = "long",
+        ArrayDims = []
+    ;
         CtorCat = ctor_cat_builtin(cat_builtin_string),
         String = "java.lang.String",
         ArrayDims = []
@@ -4176,6 +4182,13 @@ java_builtin_type(MLDS_Type, JavaUnboxedType, JavaBoxedType, UnboxMethod) :-
                 JavaBoxedType = "java.lang.Short",
                 UnboxMethod = "shortValue"
             ;
+                ( BuiltinType = builtin_type_int(int_type_int64)
+                ; BuiltinType = builtin_type_int(int_type_uint64)
+                ),
+                JavaUnboxedType = "long",
+                JavaBoxedType = "java.lang.Long",
+                UnboxMethod = "longValue"
+            ;
                 BuiltinType = builtin_type_float,
                 JavaUnboxedType = "double",
                 JavaBoxedType = "java.lang.Double",
@@ -4326,6 +4339,8 @@ output_std_unop_for_java(Info, UnaryOp, Expr, !IO) :-
         ; UnaryOp = bitwise_complement(int_type_uint), UnaryOpStr = "~"
         ; UnaryOp = bitwise_complement(int_type_int32), UnaryOpStr = "~"
         ; UnaryOp = bitwise_complement(int_type_uint32), UnaryOpStr = "~"
+        ; UnaryOp = bitwise_complement(int_type_int64), UnaryOpStr = "~"
+        ; UnaryOp = bitwise_complement(int_type_uint64), UnaryOpStr = "~"
         ; UnaryOp = logical_not, UnaryOpStr = "!"
         ; UnaryOp = hash_string,  UnaryOpStr = "mercury.String.hash_1_f_0"
         ; UnaryOp = hash_string2, UnaryOpStr = "mercury.String.hash2_1_f_0"
@@ -4444,6 +4459,28 @@ output_binop_for_java(Info, Op, X, Y, !IO) :-
         ; Op = bitwise_xor(int_type_uint32)
         ; Op = unchecked_left_shift(int_type_uint32)
         ; Op = unchecked_right_shift(int_type_uint32)
+        ; Op = int_lt(int_type_int64)
+        ; Op = int_gt(int_type_int64)
+        ; Op = int_le(int_type_int64)
+        ; Op = int_ge(int_type_int64)
+        ; Op = int_add(int_type_int64)
+        ; Op = int_sub(int_type_int64)
+        ; Op = int_mul(int_type_int64)
+        ; Op = int_div(int_type_int64)
+        ; Op = int_mod(int_type_int64)
+        ; Op = bitwise_and(int_type_int64)
+        ; Op = bitwise_or(int_type_int64)
+        ; Op = bitwise_xor(int_type_int64)
+        ; Op = unchecked_left_shift(int_type_int64)
+        ; Op = unchecked_right_shift(int_type_int64)
+        ; Op = int_add(int_type_uint64)
+        ; Op = int_sub(int_type_uint64)
+        ; Op = int_mul(int_type_uint64)
+        ; Op = bitwise_and(int_type_uint64)
+        ; Op = bitwise_or(int_type_uint64)
+        ; Op = bitwise_xor(int_type_uint64)
+        ; Op = unchecked_left_shift(int_type_uint64)
+        ; Op = unchecked_right_shift(int_type_uint64)
         ; Op = logical_and
         ; Op = logical_or
         ; Op = eq(_)
@@ -4514,6 +4551,20 @@ output_binop_for_java(Info, Op, X, Y, !IO) :-
         output_rval_for_java(Info, Y, !IO),
         io.write_string(") & 0xffffffffL))", !IO)
     ;
+        ( Op = int_lt(int_type_uint64), RelOpStr = "<"
+        ; Op = int_gt(int_type_uint64), RelOpStr = ">"
+        ; Op = int_le(int_type_uint64), RelOpStr = "<="
+        ; Op = int_ge(int_type_uint64), RelOpStr = ">="
+        ),
+        io.write_string("(java.lang.Long.compareUnsigned(", !IO),
+        output_rval_for_java(Info, X, !IO),
+        io.write_string(", ", !IO),
+        output_rval_for_java(Info, Y, !IO),
+        io.write_string(") ", !IO),
+        io.write_string(RelOpStr, !IO),
+        io.write_string(" 0)", !IO)
+
+    ;
         ( Op = int_div(int_type_uint)
         ; Op = int_mod(int_type_uint)
         ; Op = int_div(int_type_uint32)
@@ -4527,6 +4578,20 @@ output_binop_for_java(Info, Op, X, Y, !IO) :-
         output_rval_for_java(Info, Y, !IO),
         io.write_string(") & 0xffffffffL)))", !IO)
     ;
+        Op = int_div(int_type_uint64),
+        io.write_string("java.lang.Long.divideUnsigned(", !IO),
+        output_rval_for_java(Info, X, !IO),
+        io.write_string(", ", !IO),
+        output_rval_for_java(Info, Y, !IO),
+        io.write_string(")", !IO)
+    ;
+        Op = int_mod(int_type_uint64),
+        io.write_string("java.lang.Long.remainderUnsigned(", !IO),
+        output_rval_for_java(Info, X, !IO),
+        io.write_string(", ", !IO),
+        output_rval_for_java(Info, Y, !IO),
+        io.write_string(")", !IO)
+    ;
         ( Op = int_add(int_type_int8)
         ; Op = int_sub(int_type_int8)
         ; Op = int_mul(int_type_int8)
@@ -4714,6 +4779,7 @@ output_binary_op_for_java(Op, !IO) :-
             ; IntType = int_type_int8
             ; IntType = int_type_int16
             ; IntType = int_type_int32
+            ; IntType = int_type_int64
             ),
             OpStr = ">>"
         ;
@@ -4721,6 +4787,7 @@ output_binary_op_for_java(Op, !IO) :-
             ; IntType = int_type_uint8
             ; IntType = int_type_uint16
             ; IntType = int_type_uint32
+            ; IntType = int_type_uint64
             ),
             OpStr = ">>>"
         ),
@@ -4788,6 +4855,16 @@ output_rval_const_for_java(Info, Const, !IO) :-
         Const = mlconst_uint32(U32),
         io.write_int32(int32.cast_from_uint32(U32), !IO)
     ;
+        % XXX INT64.
+        Const = mlconst_int64(I64),
+        io.write_int(I64, !IO),
+        io.write_string("L", !IO)
+    ;
+        % XXX INT64.
+        Const = mlconst_uint64(U64),
+        io.write_int(U64, !IO),
+        io.write_string("L", !IO)
+    ;
         Const = mlconst_char(N),
         io.write_string("(", !IO),
         output_int_const_for_java(N, !IO),
diff --git a/compiler/mlds_to_target_util.m b/compiler/mlds_to_target_util.m
index 5106bee..9b7ac59 100644
--- a/compiler/mlds_to_target_util.m
+++ b/compiler/mlds_to_target_util.m
@@ -750,6 +750,8 @@ method_ptrs_in_rval(Rval, !CodeAddrsInConsts) :-
             ; RvalConst = mlconst_uint16(_)
             ; RvalConst = mlconst_int32(_)
             ; RvalConst = mlconst_uint32(_)
+            ; RvalConst = mlconst_int64(_)
+            ; RvalConst = mlconst_uint64(_)
             ; RvalConst = mlconst_char(_)
             ; RvalConst = mlconst_enum(_, _)
             ; RvalConst = mlconst_foreign(_, _, _)
diff --git a/compiler/mode_util.m b/compiler/mode_util.m
index 2ba11a8..54fa566 100644
--- a/compiler/mode_util.m
+++ b/compiler/mode_util.m
@@ -1900,6 +1900,8 @@ cons_id_to_shared_inst(ModuleInfo, ConsId, NumArgs) = MaybeInst :-
         ; ConsId = uint16_const(_)
         ; ConsId = int32_const(_)
         ; ConsId = uint32_const(_)
+        ; ConsId = int64_const(_)
+        ; ConsId = uint64_const(_)
         ; ConsId = float_const(_)
         ; ConsId = char_const(_)
         ; ConsId = string_const(_)
diff --git a/compiler/module_qual.qualify_items.m b/compiler/module_qual.qualify_items.m
index 322154b..03b775e 100644
--- a/compiler/module_qual.qualify_items.m
+++ b/compiler/module_qual.qualify_items.m
@@ -499,6 +499,12 @@ qualify_type(InInt, ErrorContext, Type0, Type, !Info, !Specs) :-
             BuiltinType = builtin_type_int(int_type_uint32),
             mq_info_set_module_used(InInt, unqualified("uint32"), !Info)
         ;
+            BuiltinType = builtin_type_int(int_type_int64),
+            mq_info_set_module_used(InInt, unqualified("int64"), !Info)
+        ;
+            BuiltinType = builtin_type_int(int_type_uint64),
+            mq_info_set_module_used(InInt, unqualified("uint64"), !Info)
+        ;
             BuiltinType = builtin_type_float,
             mq_info_set_module_used(InInt, unqualified("float"), !Info)
         ;
@@ -747,6 +753,8 @@ qualify_bound_inst(InInt, ErrorContext, BoundInst0, BoundInst,
         ; ConsId = uint16_const(_)
         ; ConsId = int32_const(_)
         ; ConsId = uint32_const(_)
+        ; ConsId = int64_const(_)
+        ; ConsId = uint64_const(_)
         ; ConsId = float_const(_)
         ; ConsId = char_const(_)
         ; ConsId = string_const(_)
diff --git a/compiler/opt_debug.m b/compiler/opt_debug.m
index 19c71b1..f2e76c0 100644
--- a/compiler/opt_debug.m
+++ b/compiler/opt_debug.m
@@ -463,6 +463,12 @@ dump_const(MaybeProcLabel, Const) = Str :-
         Const = llconst_uint32(U32),
         Str = uint32_to_string(U32)
     ;
+        Const = llconst_int64(I64),
+        Str = int_to_string(I64)  % XXX INT64.
+    ;
+        Const = llconst_uint64(U64),
+        Str = int_to_string(U64)  % XXX INT64.
+    ;
         Const = llconst_foreign(F, _),
         Str = F
     ;
diff --git a/compiler/opt_util.m b/compiler/opt_util.m
index 6f7950c..99b93cf 100644
--- a/compiler/opt_util.m
+++ b/compiler/opt_util.m
@@ -2623,6 +2623,8 @@ replace_labels_rval_const(Const0, Const, ReplMap) :-
         ; Const0 = llconst_uint16(_)
         ; Const0 = llconst_int32(_)
         ; Const0 = llconst_uint32(_)
+        ; Const0 = llconst_int64(_)
+        ; Const0 = llconst_uint64(_)
         ; Const0 = llconst_foreign(_, _)
         ; Const0 = llconst_float(_)
         ; Const0 = llconst_string(_)
diff --git a/compiler/options.m b/compiler/options.m
index d2ef763..25bbd3e 100644
--- a/compiler/options.m
+++ b/compiler/options.m
@@ -481,6 +481,7 @@
 
     ;       conf_low_tag_bits
     ;       unboxed_float
+    ;       unboxed_int64s
     ;       unboxed_enums
     ;       unboxed_no_tag_types
     ;       arg_pack_bits
@@ -1439,6 +1440,7 @@ option_defaults_2(compilation_model_option, [
                                         % above default with a value determined
                                         % at configuration time.
     unboxed_float                       -   bool(no),
+    unboxed_int64s                      -   bool(no),
     unboxed_enums                       -   bool(yes),
     unboxed_no_tag_types                -   bool(yes),
     arg_pack_bits                       -   int(-1),
@@ -2386,6 +2388,7 @@ long_option("bits-per-word",        bits_per_word).
 long_option("bytes-per-word",       bytes_per_word).
 long_option("conf-low-tag-bits",    conf_low_tag_bits).
 long_option("unboxed-float",        unboxed_float).
+long_option("unboxed-int64s",       unboxed_int64s).
 long_option("unboxed-enums",        unboxed_enums).
 long_option("unboxed-no-tag-types", unboxed_no_tag_types).
 long_option("arg-pack-bits",        arg_pack_bits).
@@ -4924,13 +4927,21 @@ options_help_compilation_model -->
         % This is a developer only option.
 %       "--unboxed-float",
 %       "(This option is not for general use.)",
-%       "\tDon't box floating point numbers.",
+%       "\tDo not box floating point numbers.",
 %       "\tThis assumes that a Mercury float will fit in a word.",
-%       "\tThe C code needs to be compiled with `-UBOXED_FLOAT'.",
+%       "\tThe C code needs to be compiled with `-UMR_BOXED_FLOAT'.",
 %       "\tIt may also need to be compiled with",
-%       "\t`-DUSE_SINGLE_PREC_FLOAT', if double precision",
+%       "\t`-DMR_USE_SINGLE_PREC_FLOAT', if double precision",
 %       "\tfloats don't fit into a word."
 
+%        % This is a developer only option.
+%        "--unboxed-int64s",
+%        "(This option is not for general use.)",
+%        "\tDo not box 64-bit integer numbers",
+%        "\tThis assumes that word size of the target machine is at least",
+%        "\t64-bits in size.",
+%        "\tThe C code needs to be compiled iwth `-UMR_BOXED_INT64S'.",
+
         % This is a developer only option.
 %       "--no-unboxed-enums",
 %       "(This option is not for general use.)",
diff --git a/compiler/parse_tree_to_term.m b/compiler/parse_tree_to_term.m
index a24357a..fa7d46b 100644
--- a/compiler/parse_tree_to_term.m
+++ b/compiler/parse_tree_to_term.m
@@ -676,6 +676,14 @@ cons_id_and_args_to_term_full(ConsId, ArgTerms, Term) :-
         term.context_init(Context),
         Term = uint32_to_decimal_term(UInt32, Context)
     ;
+        ConsId = int64_const(Int64),
+        term.context_init(Context),
+        Term = int_to_decimal_term(Int64, Context) % XXX INT64
+    ;
+        ConsId = uint64_const(UInt64),
+        term.context_init(Context),
+        Term = int_to_decimal_term(UInt64, Context) % XXX INT64
+    ;
         ConsId = float_const(Float),
         term.context_init(Context),
         Term = term.functor(term.float(Float), [], Context)
diff --git a/compiler/parse_type_name.m b/compiler/parse_type_name.m
index a215520..e401b62 100644
--- a/compiler/parse_type_name.m
+++ b/compiler/parse_type_name.m
@@ -662,6 +662,12 @@ is_known_type_name_args(Name, Args, KnownType) :-
             Name = "uint32",
             BuiltinType = builtin_type_int(int_type_uint32)
         ;
+            Name = "int64",
+            BuiltinType = builtin_type_int(int_type_int64)
+        ;
+            Name = "uint64",
+            BuiltinType = builtin_type_int(int_type_uint64)
+        ;
             Name = "float",
             BuiltinType = builtin_type_float
         ;
diff --git a/compiler/polymorphism.m b/compiler/polymorphism.m
index 940e898..afc77e3 100644
--- a/compiler/polymorphism.m
+++ b/compiler/polymorphism.m
@@ -3584,6 +3584,12 @@ get_category_name(CtorCat) = MaybeName :-
         CtorCat = ctor_cat_builtin(cat_builtin_int(int_type_uint32)),
         MaybeName = yes("uint32")
     ;
+        CtorCat = ctor_cat_builtin(cat_builtin_int(int_type_int64)),
+        MaybeName = yes("int64")
+    ;
+        CtorCat = ctor_cat_builtin(cat_builtin_int(int_type_uint64)),
+        MaybeName = yes("uint64")
+    ;
         CtorCat = ctor_cat_builtin(cat_builtin_char),
         MaybeName = yes("character")
     ;
diff --git a/compiler/prog_data.m b/compiler/prog_data.m
index 031a9d8..e122e49 100644
--- a/compiler/prog_data.m
+++ b/compiler/prog_data.m
@@ -113,6 +113,8 @@
     ;       uint16_const(uint16)
     ;       int32_const(int32)
     ;       uint32_const(uint32)
+    ;       int64_const(int)    % XXX INT64
+    ;       uint64_const(int)   % XXX INT64
     ;       float_const(float)
     ;       char_const(char)
     ;       string_const(string)
@@ -236,6 +238,8 @@ cons_id_is_const_struct(ConsId, ConstNum) :-
         ; ConsId = uint16_const(_)
         ; ConsId = int32_const(_)
         ; ConsId = uint32_const(_)
+        ; ConsId = int64_const(_)
+        ; ConsId = uint64_const(_)
         ; ConsId = float_const(_)
         ; ConsId = char_const(_)
         ; ConsId = string_const(_)
@@ -528,7 +532,9 @@ cons_id_is_const_struct(ConsId, ConstNum) :-
     ;       int_type_int16
     ;       int_type_uint16
     ;       int_type_int32
-    ;       int_type_uint32.
+    ;       int_type_uint32
+    ;       int_type_int64
+    ;       int_type_uint64.
 
 :- pred is_builtin_type_sym_name(sym_name::in) is semidet.
 
@@ -604,6 +610,8 @@ builtin_type_to_string(builtin_type_int(int_type_int16), "int16").
 builtin_type_to_string(builtin_type_int(int_type_uint16), "uint16").
 builtin_type_to_string(builtin_type_int(int_type_int32), "int32").
 builtin_type_to_string(builtin_type_int(int_type_uint32), "uint32").
+builtin_type_to_string(builtin_type_int(int_type_int64), "int64").
+builtin_type_to_string(builtin_type_int(int_type_uint64), "uint64").
 builtin_type_to_string(builtin_type_float, "float").
 builtin_type_to_string(builtin_type_string, "string").
 builtin_type_to_string(builtin_type_char, "character").
@@ -618,6 +626,8 @@ int_type_to_string(int_type_int16, "int16").
 int_type_to_string(int_type_uint16,  "uint16").
 int_type_to_string(int_type_int32, "int32").
 int_type_to_string(int_type_uint32, "uint32").
+int_type_to_string(int_type_int64, "int64").
+int_type_to_string(int_type_uint64, "uint64").
 
 tvarset_merge_renaming(TVarSetA, TVarSetB, TVarSet, Renaming) :-
     varset.merge_renaming(TVarSetA, TVarSetB, TVarSet, Renaming).
diff --git a/compiler/prog_out.m b/compiler/prog_out.m
index 1443147..d88740c 100644
--- a/compiler/prog_out.m
+++ b/compiler/prog_out.m
@@ -390,6 +390,12 @@ cons_id_and_arity_to_string_maybe_quoted(MangleCons, QuoteCons, ConsId)
         ConsId = uint32_const(UInt32),
         String = string.uint32_to_string(UInt32)
     ;
+        ConsId = int64_const(Int64),
+        String = string.int_to_string(Int64) % XXX INT64
+    ;
+        ConsId = uint64_const(UInt64),
+        String = string.int_to_string(UInt64) % XXX INT64
+    ;
         ConsId = float_const(Float),
         String = float_to_string(Float)
     ;
diff --git a/compiler/prog_rep.m b/compiler/prog_rep.m
index 50c2ffc..96576d1 100644
--- a/compiler/prog_rep.m
+++ b/compiler/prog_rep.m
@@ -874,6 +874,8 @@ cons_id_rep(int16_const(Int16)) = string.int16_to_string(Int16).
 cons_id_rep(uint16_const(UInt16)) = string.uint16_to_string(UInt16).
 cons_id_rep(int32_const(Int32)) = string.int32_to_string(Int32).
 cons_id_rep(uint32_const(UInt32)) = string.uint32_to_string(UInt32).
+cons_id_rep(int64_const(Int64)) = string.int_to_string(Int64).    % XXX INT64.
+cons_id_rep(uint64_const(UInt64)) = string.int_to_string(UInt64). % XXX INT64.
 cons_id_rep(float_const(Float)) = string.float_to_string(Float).
 cons_id_rep(char_const(Char)) = string.char_to_string(Char).
 cons_id_rep(string_const(String)) = """" ++ String ++ """".
diff --git a/compiler/prog_rep_tables.m b/compiler/prog_rep_tables.m
index 6f4bb5f..5f4cc20 100644
--- a/compiler/prog_rep_tables.m
+++ b/compiler/prog_rep_tables.m
@@ -365,6 +365,12 @@ add_type_to_table(Type, TypeCode, !StringTable, !TypeTable) :-
         ;
             BuiltinType = builtin_type_int(int_type_uint32),
             Selector = 19
+        ;
+            BuiltinType = builtin_type_int(int_type_int64),
+            Selector = 20
+        ;
+            BuiltinType = builtin_type_int(int_type_uint64),
+            Selector = 21
         ),
         TypeBytesCord = cord.singleton(Selector)
     ;
diff --git a/compiler/prog_type.m b/compiler/prog_type.m
index 06b2b30..e7c39b3 100644
--- a/compiler/prog_type.m
+++ b/compiler/prog_type.m
@@ -933,6 +933,8 @@ qualify_cons_id(Args, ConsId0, ConsId, InstConsId) :-
         ; ConsId0 = uint16_const(_)
         ; ConsId0 = int32_const(_)
         ; ConsId0 = uint32_const(_)
+        ; ConsId0 = int64_const(_)
+        ; ConsId0 = uint64_const(_)
         ; ConsId0 = float_const(_)
         ; ConsId0 = char_const(_)
         ; ConsId0 = string_const(_)
diff --git a/compiler/prog_util.m b/compiler/prog_util.m
index 5692487..91395f6 100644
--- a/compiler/prog_util.m
+++ b/compiler/prog_util.m
@@ -663,6 +663,8 @@ cons_id_arity(ConsId) = Arity :-
         ; ConsId = uint16_const(_)
         ; ConsId = int32_const(_)
         ; ConsId = uint32_const(_)
+        ; ConsId = int64_const(_)
+        ; ConsId = uint64_const(_)
         ; ConsId = float_const(_)
         ; ConsId = char_const(_)
         ; ConsId = string_const(_)
@@ -694,6 +696,8 @@ cons_id_maybe_arity(int16_const(_)) = yes(0).
 cons_id_maybe_arity(uint16_const(_)) = yes(0).
 cons_id_maybe_arity(int32_const(_)) = yes(0).
 cons_id_maybe_arity(uint32_const(_)) = yes(0).
+cons_id_maybe_arity(int64_const(_)) = yes(0).
+cons_id_maybe_arity(uint64_const(_)) = yes(0).
 cons_id_maybe_arity(float_const(_)) = yes(0).
 cons_id_maybe_arity(char_const(_)) = yes(0).
 cons_id_maybe_arity(string_const(_)) = yes(0).
diff --git a/compiler/rbmm.execution_path.m b/compiler/rbmm.execution_path.m
index 0722da5..e1ad5ca 100644
--- a/compiler/rbmm.execution_path.m
+++ b/compiler/rbmm.execution_path.m
@@ -236,6 +236,8 @@ execution_paths_covered_cases(ProcInfo, Switch, [Case | Cases], !ExecPaths) :-
         ; MainConsId = uint16_const(_UInt16)
         ; MainConsId = int32_const(_Int32)
         ; MainConsId = uint32_const(_UInt32)
+        ; MainConsId = int64_const(_Int64)
+        ; MainConsId = uint64_const(_UInt64)
         ; MainConsId = float_const(_Float)
         ; MainConsId = char_const(_Char)
         ; MainConsId = string_const(_String)
diff --git a/compiler/rtti.m b/compiler/rtti.m
index 94ad67e..4d60d86 100644
--- a/compiler/rtti.m
+++ b/compiler/rtti.m
@@ -2418,6 +2418,10 @@ table_trie_step_to_c(table_trie_step_int(int_type_int32),
     "MR_TABLE_STEP_INT32", no).
 table_trie_step_to_c(table_trie_step_int(int_type_uint32),
     "MR_TABLE_STEP_UINT32", no).
+table_trie_step_to_c(table_trie_step_int(int_type_int64),
+    "MR_TABLE_STEP_INT64", no).
+table_trie_step_to_c(table_trie_step_int(int_type_uint64),
+    "MR_TABLE_STEP_UINT64", no).
 table_trie_step_to_c(table_trie_step_char, "MR_TABLE_STEP_CHAR", no).
 table_trie_step_to_c(table_trie_step_string, "MR_TABLE_STEP_STRING", no).
 table_trie_step_to_c(table_trie_step_float, "MR_TABLE_STEP_FLOAT", no).
diff --git a/compiler/rtti_to_mlds.m b/compiler/rtti_to_mlds.m
index 868c3f7..5379410 100644
--- a/compiler/rtti_to_mlds.m
+++ b/compiler/rtti_to_mlds.m
@@ -1883,6 +1883,8 @@ add_rtti_defn_arcs_const(DefnGlobalVarName, Const, !Graph) :-
         ; Const = mlconst_uint16(_)
         ; Const = mlconst_int32(_)
         ; Const = mlconst_uint32(_)
+        ; Const = mlconst_int64(_)
+        ; Const = mlconst_uint64(_)
         ; Const = mlconst_enum(_, _)
         ; Const = mlconst_char(_)
         ; Const = mlconst_foreign(_, _, _)
diff --git a/compiler/stack_layout.m b/compiler/stack_layout.m
index 3128330..ffd64c5 100644
--- a/compiler/stack_layout.m
+++ b/compiler/stack_layout.m
@@ -2208,8 +2208,10 @@ represent_locn_or_const_as_int_rval(Params, LvalOrConst, Rval, Type,
     ;
         LvalOrConst = const(_Const),
         UnboxedFloats = Params ^ slp_unboxed_floats,
+        UnboxedInt64s = Params ^ slp_unboxed_int64s,
         ArgWidth = full_word,
-        LLDSType = rval_type_as_arg(UnboxedFloats, ArgWidth, LvalOrConst),
+        LLDSType = rval_type_as_arg(UnboxedFloats, UnboxedInt64s, ArgWidth,
+            LvalOrConst),
         add_scalar_static_cell([typed_rval(LvalOrConst, LLDSType)], DataId,
             !StaticCellInfo),
         Rval = const(llconst_data_addr(DataId, no)),
@@ -2594,7 +2596,10 @@ represent_determinism_rval(Detism,
                 slp_unboxed_floats          :: have_unboxed_floats,
 
                 % Do we want to include information about labels' line numbers?
-                slp_rtti_line_numbers       :: bool
+                slp_rtti_line_numbers       :: bool,
+
+                % Do we have unboxed 64-bit integer types?
+                slp_unboxed_int64s          :: have_unboxed_int64s
             ).
 
 :- func init_stack_layout_params(module_info) = stack_layout_params.
@@ -2613,6 +2618,7 @@ init_stack_layout_params(ModuleInfo) = Params :-
     globals.lookup_bool_option(Globals, rtti_line_numbers, RttiLineNumbers),
     globals.lookup_int_option(Globals, layout_compression_limit,
         CompressLimit),
+    globals.lookup_bool_option(Globals, unboxed_int64s, UnboxedInt64sOpt),
     (
         UnboxedFloatOpt = no,
         UnboxedFloat = do_not_have_unboxed_floats
@@ -2627,9 +2633,16 @@ init_stack_layout_params(ModuleInfo) = Params :-
         CommonLayoutData = yes,
         CompressArrays = yes(CompressLimit)
     ),
+    (
+        UnboxedInt64sOpt = no,
+        UnboxedInt64s = do_not_have_unboxed_int64s
+    ;
+        UnboxedInt64sOpt = yes,
+        UnboxedInt64s = have_unboxed_int64s
+    ),
     Params = stack_layout_params(ModuleInfo, TraceLevel, TraceSuppress,
         DeepProfiling, AgcLayout, TraceLayout, ProcIdLayout, CompressArrays,
-        StaticCodeAddr, UnboxedFloat, RttiLineNumbers).
+        StaticCodeAddr, UnboxedFloat, RttiLineNumbers, UnboxedInt64s).
 
 %---------------------------------------------------------------------------%
 :- end_module ll_backend.stack_layout.
diff --git a/compiler/table_gen.m b/compiler/table_gen.m
index e57bc4f..f8f678e 100644
--- a/compiler/table_gen.m
+++ b/compiler/table_gen.m
@@ -3669,6 +3669,12 @@ type_save_category(CtorCat, Name) :-
         CtorCat = ctor_cat_builtin(cat_builtin_int(int_type_uint32)),
         Name = "uint32"
     ;
+        CtorCat = ctor_cat_builtin(cat_builtin_int(int_type_int64)),
+        Name = "int64"
+    ;
+        CtorCat = ctor_cat_builtin(cat_builtin_int(int_type_uint64)),
+        Name = "uint64"
+    ;
         CtorCat = ctor_cat_builtin(cat_builtin_float),
         Name = "float"
     ;
diff --git a/compiler/type_util.m b/compiler/type_util.m
index 5563a38..009f131 100644
--- a/compiler/type_util.m
+++ b/compiler/type_util.m
@@ -880,6 +880,12 @@ classify_type_ctor_if_special(TypeCtor, TypeCategory) :-
             TypeName = "uint32",
             TypeCategory = ctor_cat_builtin(cat_builtin_int(int_type_uint32))
         ;
+            TypeName = "int64",
+            TypeCategory = ctor_cat_builtin(cat_builtin_int(int_type_int64))
+        ;
+            TypeName = "uint64",
+            TypeCategory = ctor_cat_builtin(cat_builtin_int(int_type_uint64))
+        ;
             TypeName = "character",
             TypeCategory = ctor_cat_builtin(cat_builtin_char)
         ;
diff --git a/compiler/typecheck.m b/compiler/typecheck.m
index 07e679d..ee99e26 100644
--- a/compiler/typecheck.m
+++ b/compiler/typecheck.m
@@ -2804,6 +2804,8 @@ builtin_atomic_type(int16_const(_), "int16").
 builtin_atomic_type(uint16_const(_), "uint16").
 builtin_atomic_type(int32_const(_), "int32").
 builtin_atomic_type(uint32_const(_), "uint32").
+builtin_atomic_type(int64_const(_), "int64").
+builtin_atomic_type(uint64_const(_), "uint64").
 builtin_atomic_type(float_const(_), "float").
 builtin_atomic_type(char_const(_), "character").
 builtin_atomic_type(string_const(_), "string").
diff --git a/compiler/unify_gen.m b/compiler/unify_gen.m
index d7d6398..720072a 100644
--- a/compiler/unify_gen.m
+++ b/compiler/unify_gen.m
@@ -2194,6 +2194,14 @@ int_tag_to_const_and_int_type(IntTag, Const, Type) :-
         IntTag = int_tag_uint32(UInt32),
         Const = llconst_uint32(UInt32),
         Type = int_type_uint32
+    ;
+        IntTag = int_tag_int64(Int64),
+        Const = llconst_int64(Int64),
+        Type = int_type_int64
+    ;
+        IntTag = int_tag_uint64(UInt64),
+        Const = llconst_uint64(UInt64),
+        Type = int_type_uint64
     ).
 
 :- pred generate_ground_term_args(list(prog_var)::in, list(arg_width)::in,
diff --git a/compiler/unify_proc.m b/compiler/unify_proc.m
index 6d5a9c6..4b0b8fc 100644
--- a/compiler/unify_proc.m
+++ b/compiler/unify_proc.m
@@ -402,6 +402,12 @@ generate_builtin_unify(CtorCat, X, Y, Context, Clause, !Info) :-
         CtorCat = ctor_cat_builtin(cat_builtin_int(int_type_uint32)),
         Name = "builtin_unify_uint32"
     ;
+        CtorCat = ctor_cat_builtin(cat_builtin_int(int_type_int64)),
+        Name = "builtin_unify_int64"
+    ;
+        CtorCat = ctor_cat_builtin(cat_builtin_int(int_type_uint64)),
+        Name = "builtin_unify_uint64"
+    ;
         CtorCat = ctor_cat_builtin(cat_builtin_char),
         Name = "builtin_unify_character"
     ;
@@ -739,6 +745,12 @@ generate_builtin_compare(CtorCat, Res, X, Y, Context, Clause, !Info) :-
         CtorCat = ctor_cat_builtin(cat_builtin_int(int_type_uint32)),
         Name = "builtin_compare_uint32"
     ;
+        CtorCat = ctor_cat_builtin(cat_builtin_int(int_type_int64)),
+        Name = "builtin_compare_int64"
+    ;
+        CtorCat = ctor_cat_builtin(cat_builtin_int(int_type_uint64)),
+        Name = "builtin_compare_uint64"
+    ;
         CtorCat = ctor_cat_builtin(cat_builtin_char),
         Name = "builtin_compare_character"
     ;
diff --git a/compiler/unused_imports.m b/compiler/unused_imports.m
index 3b2c651..a4f1ee2 100644
--- a/compiler/unused_imports.m
+++ b/compiler/unused_imports.m
@@ -810,6 +810,8 @@ cons_id_used_modules(Visibility, ConsId, !UsedModules) :-
         ; ConsId = uint16_const(_)
         ; ConsId = int32_const(_)
         ; ConsId = uint32_const(_)
+        ; ConsId = int64_const(_)
+        ; ConsId = uint64_const(_)
         ; ConsId = float_const(_)
         ; ConsId = char_const(_)
         ; ConsId = string_const(_)
diff --git a/compiler/var_locn.m b/compiler/var_locn.m
index 81c13e3..8f94035 100644
--- a/compiler/var_locn.m
+++ b/compiler/var_locn.m
@@ -2311,7 +2311,9 @@ cell_is_constant(VarStateMap, ExprnOpts, [CellArg | CellArgs],
         fail
     ),
     expr_is_constant(VarStateMap, ExprnOpts, Rval0, Rval),
-    LldsType = rval_type_as_arg(get_unboxed_floats(ExprnOpts), ArgWidth, Rval),
+    UnboxedFloats = get_unboxed_floats(ExprnOpts),
+    UnboxedInt64s = get_unboxed_int64s(ExprnOpts),
+    LldsType = rval_type_as_arg(UnboxedFloats, UnboxedInt64s, ArgWidth, Rval),
     cell_is_constant(VarStateMap, ExprnOpts, CellArgs, TypedRvals).
 
     % expr_is_constant(VarStateMap, ExprnOpts, Rval0, Rval):
diff --git a/compiler/xml_documentation.m b/compiler/xml_documentation.m
index c25831a..a54050f 100644
--- a/compiler/xml_documentation.m
+++ b/compiler/xml_documentation.m
@@ -715,6 +715,10 @@ cons_id_to_xml(int32_const(_)) = _ :-
     unexpected($file, $pred, "NYI int32").
 cons_id_to_xml(uint32_const(_)) = _ :-
     unexpected($file, $pred, "NYI uint32").
+cons_id_to_xml(int64_const(_)) = _ :-
+    unexpected($file, $pred, "NYI int64").
+cons_id_to_xml(uint64_const(_)) = _ :-
+    unexpected($file, $pred, "NYI uint64").
 cons_id_to_xml(float_const(F)) = tagged_float("float", F).
 cons_id_to_xml(char_const(C)) = tagged_char("char", C).
 cons_id_to_xml(string_const(S)) = tagged_string("string", S).
diff --git a/configure.ac b/configure.ac
index fcd1f52..7012010 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2325,6 +2325,14 @@ AC_SUBST(MR_LONG_DOUBLE_IS_64_BIT)
 
 #-----------------------------------------------------------------------------#
 
+# XXX INT64 -- while we are boostrapping the changes that introduce int64
+# and uint65, we always box them.  Support for unboxed 64-bit integer types
+# will be enabled later.
+
+AC_DEFINE(MR_BOXED_INT64S)
+
+#-----------------------------------------------------------------------------#
+
 # The number of detstack slots (words) that a MR_SyncTerm occupies.
 SYNC_TERM_SIZE=3
 AC_SUBST(SYNC_TERM_SIZE)
diff --git a/deep_profiler/program_representation_utils.m b/deep_profiler/program_representation_utils.m
index ec17e88..0c40969 100644
--- a/deep_profiler/program_representation_utils.m
+++ b/deep_profiler/program_representation_utils.m
@@ -322,6 +322,12 @@ type_rep_to_strings(TypeRep, Cord) :-
             BuiltinTypeRep = builtin_type_uint32_rep,
             TypeNameStr = "uint32"
         ;
+            BuiltinTypeRep = builtin_type_int64_rep,
+            TypeNameStr = "int64"
+        ;
+            BuiltinTypeRep = builtin_type_uint64_rep,
+            TypeNameStr = "uint64"
+        ;
             BuiltinTypeRep = builtin_type_float_rep,
             TypeNameStr = "float"
         ;
diff --git a/doc/reference_manual.texi b/doc/reference_manual.texi
index 1dc7f8a..375dc6f 100644
--- a/doc/reference_manual.texi
+++ b/doc/reference_manual.texi
@@ -2199,10 +2199,12 @@ int
 int8
 int16
 int32
+int64
 uint
 uint8
 uint16
 uint32
+uint64
 float
 character
 string
@@ -7148,10 +7150,12 @@ The Mercury primitive types are mapped to the following C types:
   @item @code{int8}   @tab @code{int8_t}
   @item @code{int16}  @tab @code{int16_t}
   @item @code{int32}  @tab @code{int32_t}
+ at c  @item @code{int64}  @tab @code{int64_t}
   @item @code{uint}   @tab @code{MR_Unsigned}
   @item @code{uint8}  @tab @code{uint8_t}
   @item @code{uint16} @tab @code{uint16_t}
   @item @code{uint32} @tab @code{uint32_t}
+ at c  @item @code{uint64} @tab @code{uint64_t}
   @item @code{float}  @tab @code{MR_Float}
   @item @code{char}   @tab @code{MR_Char}
   @item @code{string} @tab @code{MR_String}
@@ -7245,10 +7249,12 @@ Infrastructure (CLI) and C# types:
   @item @code{int8}   @tab @code{System.Int8}   @tab @code{sbyte}
   @item @code{int16}  @tab @code{System.Int16}  @tab @code{short}
   @item @code{int32}  @tab @code{System.Int32}  @tab @code{int}
+ at c  @item @code{int64}  @tab @code{System.Int64}  @tab @code{long}
   @item @code{uint}   @tab @code{System.UInt32} @tab @code{uint}
   @item @code{uint8}  @tab @code{System.UInt8}  @tab @code{byte}
   @item @code{uint16} @tab @code{System.UInt16} @tab @code{ushort}
   @item @code{uint32} @tab @code{System.UInt32} @tab @code{uint}
+ at c  @item @code{uint64} @tab @code{System.UInt64} @tab @code{ulong}
   @item @code{float}  @tab @code{System.Double} @tab @code{double}
   @item @code{char}   @tab @code{System.Int32}  @tab @code{int}
   @item @code{string} @tab @code{System.String} @tab @code{string}
@@ -7374,10 +7380,12 @@ The Mercury primitive types are mapped to the following Java types:
   @item @code{int8}   @tab @code{byte}
   @item @code{int16}  @tab @code{short}
   @item @code{int32}  @tab @code{int}
+ at c  @item @code{int64}  @tab @code{long}
   @item @code{uint}   @tab @code{int}
   @item @code{uint8}  @tab @code{byte}
   @item @code{uint16} @tab @code{short}
   @item @code{uint32} @tab @code{int}
+ at c  @item @code{uint64}  @tab @code{long}
   @item @code{float}  @tab @code{double}
   @item @code{char}   @tab @code{int}
   @item @code{string} @tab @code{java.lang.String}
diff --git a/java/runtime/TypeCtorRep.java b/java/runtime/TypeCtorRep.java
index dc241a9..280d8ed 100644
--- a/java/runtime/TypeCtorRep.java
+++ b/java/runtime/TypeCtorRep.java
@@ -61,8 +61,10 @@ public class TypeCtorRep implements java.io.Serializable {
         public static final int MR_TYPECTOR_REP_UINT16                  = 50;
         public static final int MR_TYPECTOR_REP_INT32                   = 51;
         public static final int MR_TYPECTOR_REP_UINT32                  = 52;
-        public static final int MR_TYPECTOR_REP_UNKNOWN                 = 53;
-        public static final int MR_TYPECTOR_REP_MAX                     = 54;
+        public static final int MR_TYPECTOR_REP_INT64                   = 53;
+        public static final int MR_TYPECTOR_REP_UINT64                  = 54;
+        public static final int MR_TYPECTOR_REP_UNKNOWN                 = 55;
+        public static final int MR_TYPECTOR_REP_MAX                     = 56;
 
         // Instance variable for TypeCtorRep objects.
 	
diff --git a/library/MODULES_UNDOC b/library/MODULES_UNDOC
index b1cd56f..28e5613 100644
--- a/library/MODULES_UNDOC
+++ b/library/MODULES_UNDOC
@@ -1,6 +1,7 @@
 backjump.m
 erlang_builtin.m
 erlang_rtti_implementation.m
+int64.m
 mer_std.m
 mutvar.m
 par_builtin.m
@@ -17,3 +18,4 @@ string.to_string.m
 table_builtin.m
 term_size_prof_builtin.m
 test_bitset.m
+uint64.m
diff --git a/library/construct.m b/library/construct.m
index 815c15c..e248ed7 100644
--- a/library/construct.m
+++ b/library/construct.m
@@ -465,6 +465,8 @@ get_functor_ordinal(TypeDesc, FunctorNumber, Ordinal) :-
         case MR_TYPECTOR_REP_UINT16:
         case MR_TYPECTOR_REP_INT32:
         case MR_TYPECTOR_REP_UINT32:
+        case MR_TYPECTOR_REP_INT64:
+        case MR_TYPECTOR_REP_UINT64:
         case MR_TYPECTOR_REP_FLOAT:
         case MR_TYPECTOR_REP_CHAR:
         case MR_TYPECTOR_REP_STRING:
@@ -942,6 +944,18 @@ find_functor_2(TypeInfo, Functor, Arity, Num0, FunctorNumber, ArgTypes) :-
                 ""cannot construct uint32 with construct.construct"");
             break;
 
+        case MR_TYPECTOR_REP_INT64:
+            /* int64s don't have functor ordinals. */
+            MR_fatal_error(
+                ""cannot construct int64 with construct.construct"");
+            break;
+
+        case MR_TYPECTOR_REP_UINT64:
+            /* uint64s don't have functor ordinals. */
+            MR_fatal_error(
+                ""cannot construct uint64 with construct.construct"");
+            break;
+
         case MR_TYPECTOR_REP_FLOAT:
             /* floats don't have functor ordinals. */
             MR_fatal_error(
diff --git a/library/erlang_rtti_implementation.m b/library/erlang_rtti_implementation.m
index 0ad224e..ba6e78e 100644
--- a/library/erlang_rtti_implementation.m
+++ b/library/erlang_rtti_implementation.m
@@ -174,6 +174,8 @@
     ;       etcr_uint16
     ;       etcr_int32
     ;       etcr_uint32
+    ;       etcr_int64
+    ;       etcr_uint64
     ;       etcr_float
     ;       etcr_char
     ;       etcr_string
@@ -885,6 +887,20 @@ deconstruct_2(Term, TypeInfo, TypeCtorInfo, TypeCtorRep, NonCanon,
         Arity = 0,
         Arguments = []
     ;
+        TypeCtorRep = etcr_int64,
+        % XXX INT64
+        Functor = "<<int64>>",
+        FunctorNumber = 0,
+        Arity = 0,
+        Arguments = []
+    ;
+        TypeCtorRep = etcr_uint64,
+        % XXX INT64
+        Functor = "<<uint64>>",
+        FunctorNumber = 0,
+        Arity = 0,
+        Arguments = []
+    ;
         TypeCtorRep = etcr_float,
         det_dynamic_cast(Term, Float),
         Functor = float_to_string(Float),
@@ -1252,6 +1268,8 @@ num_functors(TypeInfo, MaybeNumFunctors) :-
         ; TypeCtorRep = etcr_uint16
         ; TypeCtorRep = etcr_int32
         ; TypeCtorRep = etcr_uint32
+        ; TypeCtorRep = etcr_int64
+        ; TypeCtorRep = etcr_uint64
         ; TypeCtorRep = etcr_float
         ; TypeCtorRep = etcr_char
         ; TypeCtorRep = etcr_string
@@ -1376,6 +1394,8 @@ get_functor_with_names(TypeInfo, NumFunctor) = Result :-
         ; TypeCtorRep = etcr_uint16
         ; TypeCtorRep = etcr_int32
         ; TypeCtorRep = etcr_uint32
+        ; TypeCtorRep = etcr_int64
+        ; TypeCtorRep = etcr_uint64
         ; TypeCtorRep = etcr_float
         ; TypeCtorRep = etcr_char
         ; TypeCtorRep = etcr_string
@@ -1535,6 +1555,8 @@ construct(TypeDesc, Index, Args) = Term :-
         ; TypeCtorRep = etcr_uint16
         ; TypeCtorRep = etcr_int32
         ; TypeCtorRep = etcr_uint32
+        ; TypeCtorRep = etcr_int64
+        ; TypeCtorRep = etcr_uint64
         ; TypeCtorRep = etcr_float
         ; TypeCtorRep = etcr_char
         ; TypeCtorRep = etcr_string
diff --git a/library/int64.m b/library/int64.m
new file mode 100644
index 0000000..4876351
--- /dev/null
+++ b/library/int64.m
@@ -0,0 +1,21 @@
+%---------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
+%---------------------------------------------------------------------------%
+% Copyright (C) 2018 The Mercury team.
+% This file may only be copied under the terms of the GNU Library General
+% Public License - see the file COPYING.LIB in the Mercury distribution.
+%---------------------------------------------------------------------------%
+%
+% File: int64.m
+% Main author: juliensf
+% Stability: low.
+%
+% Predicates and functions for dealing with signed 64-bit integer numbers.
+%
+%---------------------------------------------------------------------------%
+
+:- module int64.
+:- interface.
+
+:- type placeholder_int64 ---> placeholder_int64.
+
diff --git a/library/library.m b/library/library.m
index 806e7f6..c4ba781 100644
--- a/library/library.m
+++ b/library/library.m
@@ -98,6 +98,7 @@
 :- import_module int8.
 :- import_module int16.
 :- import_module int32.
+:- import_module int64.
 :- import_module integer.
 :- import_module io.
 :- import_module lazy.
@@ -155,6 +156,7 @@
 :- import_module uint8.
 :- import_module uint16.
 :- import_module uint32.
+:- import_module uint64.
 :- import_module unit.
 :- import_module univ.
 :- import_module varset.
@@ -275,6 +277,7 @@ mercury_std_library_module("int").
 mercury_std_library_module("int8").
 mercury_std_library_module("int16").
 mercury_std_library_module("int32").
+mercury_std_library_module("int64").
 mercury_std_library_module("integer").
 mercury_std_library_module("io").
 mercury_std_library_module("lazy").
@@ -350,6 +353,7 @@ mercury_std_library_module("uint").
 mercury_std_library_module("uint8").
 mercury_std_library_module("uint16").
 mercury_std_library_module("uint32").
+mercury_std_library_module("uint64").
 mercury_std_library_module("unit").
 mercury_std_library_module("univ").
 mercury_std_library_module("varset").
diff --git a/library/private_builtin.m b/library/private_builtin.m
index 37ce585..b1757c4 100644
--- a/library/private_builtin.m
+++ b/library/private_builtin.m
@@ -75,6 +75,14 @@
 :- pred builtin_compare_uint32(comparison_result::uo, uint32::in, uint32::in)
     is det.
 
+:- pred builtin_unify_int64(T::in, T::in) is semidet.
+:- pred builtin_compare_int64(comparison_result::uo, T::in, T::in)
+    is det.
+
+:- pred builtin_unify_uint64(T::in, T::in) is semidet.
+:- pred builtin_compare_uint64(comparison_result::uo, T::in, T::in)
+    is det.
+
 :- pred builtin_unify_character(character::in, character::in) is semidet.
 :- pred builtin_compare_character(comparison_result::uo, character::in,
     character::in) is det.
@@ -271,6 +279,34 @@ builtin_compare_uint32(R, X, Y) :-
         R = (>)
     ).
 
+builtin_unify_int64(_, _) :-
+    ( if semidet_succeed then
+        sorry("unify for int64")
+    else
+        semidet_succeed
+    ).
+
+builtin_compare_int64(Result, _, _) :-
+    ( if semidet_succeed then
+        sorry("compare for int64")
+    else
+        Result = (=)
+    ).
+
+builtin_unify_uint64(_, _) :-
+    ( if semidet_succeed then
+        sorry("unify for uint64")
+    else
+        semidet_succeed
+    ).
+
+builtin_compare_uint64(Result, _, _) :-
+    ( if semidet_succeed then
+        sorry("compare for uint64")
+    else
+        Result = (=)
+    ).
+
 builtin_unify_character(C, C).
 
 builtin_compare_character(R, X, Y) :-
@@ -1862,8 +1898,10 @@ const MR_FA_TypeInfo_Struct1 ML_type_info_for_list_of_pseudo_type_info = {
     public static final int MR_TYPECTOR_REP_UINT16                  = 50;
     public static final int MR_TYPECTOR_REP_INT32                   = 51;
     public static final int MR_TYPECTOR_REP_UINT32                  = 52;
-    public static final int MR_TYPECTOR_REP_UNKNOWN                 = 53;
-    public static final int MR_TYPECTOR_REP_MAX                     = 54;
+    public static final int MR_TYPECTOR_REP_INT64                   = 53;
+    public static final int MR_TYPECTOR_REP_UINT64                  = 54;
+    public static final int MR_TYPECTOR_REP_UNKNOWN                 = 55;
+    public static final int MR_TYPECTOR_REP_MAX                     = 56;
 
     public static final int MR_SECTAG_NONE              = 0;
     public static final int MR_SECTAG_NONE_DIRECT_ARG   = 1;
diff --git a/library/rtti_implementation.m b/library/rtti_implementation.m
index 699cbab..623e748 100644
--- a/library/rtti_implementation.m
+++ b/library/rtti_implementation.m
@@ -2,7 +2,7 @@
 % vim: ft=mercury ts=4 sw=4 et
 %---------------------------------------------------------------------------%
 % Copyright (C) 2001-2007, 2009-2011 The University of Melbourne.
-% Copyright (C) 2014-2016 The Mercury team.
+% Copyright (C) 2014-2018 The Mercury team.
 % This file may only be copied under the terms of the GNU Library General
 % Public License - see the file COPYING.LIB in the Mercury distribution.
 %---------------------------------------------------------------------------%
@@ -209,6 +209,8 @@
     ;       tcr_uint16
     ;       tcr_int32
     ;       tcr_uint32
+    ;       tcr_int64
+    ;       tcr_uint64
     ;       tcr_unknown.
 
     % We keep all the other types abstract.
@@ -906,6 +908,8 @@ type_info_num_functors(TypeInfo, NumFunctors) :-
         ; TypeCtorRep = tcr_uint16
         ; TypeCtorRep = tcr_int32
         ; TypeCtorRep = tcr_uint32
+        ; TypeCtorRep = tcr_int64
+        ; TypeCtorRep = tcr_uint64
         ; TypeCtorRep = tcr_char
         ; TypeCtorRep = tcr_float
         ; TypeCtorRep = tcr_string
@@ -1017,6 +1021,8 @@ get_functor_impl(TypeInfo, FunctorNumber,
         ; TypeCtorRep = tcr_uint16
         ; TypeCtorRep = tcr_int32
         ; TypeCtorRep = tcr_uint32
+        ; TypeCtorRep = tcr_int64
+        ; TypeCtorRep = tcr_uint64
         ; TypeCtorRep = tcr_char
         ; TypeCtorRep = tcr_float
         ; TypeCtorRep = tcr_string
@@ -1254,6 +1260,8 @@ type_info_get_functor_ordinal(TypeInfo, FunctorNum, Ordinal) :-
         ; TypeCtorRep = tcr_uint16
         ; TypeCtorRep = tcr_int32
         ; TypeCtorRep = tcr_uint32
+        ; TypeCtorRep = tcr_int64
+        ; TypeCtorRep = tcr_uint64
         ; TypeCtorRep = tcr_float
         ; TypeCtorRep = tcr_char
         ; TypeCtorRep = tcr_string
@@ -2790,6 +2798,20 @@ deconstruct_2(Term, TypeInfo, TypeCtorInfo, TypeCtorRep, NonCanon,
         Arity = 0,
         Arguments = []
     ;
+        TypeCtorRep = tcr_int64,
+        % XXX INT64
+        Functor = "<<int64>>",
+        Ordinal = -1,
+        Arity = 0,
+        Arguments = []
+    ;
+        TypeCtorRep = tcr_uint64,
+        % XXX INT64
+        Functor = "<<uint64>>",
+        Ordinal = -1,
+        Arity = 0,
+        Arguments = []
+    ;
         TypeCtorRep = tcr_char,
         det_dynamic_cast(Term, Char),
         Functor = string.from_char_list(['\'', Char, '\'']),
@@ -3062,6 +3084,8 @@ univ_named_arg_2(Term, TypeInfo, TypeCtorInfo, TypeCtorRep, NonCanon, Name,
         ; TypeCtorRep = tcr_uint16
         ; TypeCtorRep = tcr_int32
         ; TypeCtorRep = tcr_uint32
+        ; TypeCtorRep = tcr_int64
+        ; TypeCtorRep = tcr_uint64
         ; TypeCtorRep = tcr_char
         ; TypeCtorRep = tcr_float
         ; TypeCtorRep = tcr_string
diff --git a/library/table_statistics.m b/library/table_statistics.m
index 9fcd773..6032b6b 100644
--- a/library/table_statistics.m
+++ b/library/table_statistics.m
@@ -69,7 +69,9 @@
     ;       table_step_int16
     ;       table_step_uint16
     ;       table_step_int32
-    ;       table_step_uint32.
+    ;       table_step_uint32
+    ;       table_step_int64
+    ;       table_step_uint64.
 
 :- type table_step_stats
     --->    table_step_stats(
diff --git a/library/uint64.m b/library/uint64.m
new file mode 100644
index 0000000..be4664d
--- /dev/null
+++ b/library/uint64.m
@@ -0,0 +1,21 @@
+%---------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
+%---------------------------------------------------------------------------%
+% Copyright (C) 2018 The Mercury team.
+% This file may only be copied under the terms of the GNU Library General
+% Public License - see the file COPYING.LIB in the Mercury distribution.
+%---------------------------------------------------------------------------%
+%
+% File: uint64.m
+% Main author: juliensf
+% Stability: low.
+%
+% Predicates and functions for dealing with unsigned 64-bit integer numbers.
+%
+%---------------------------------------------------------------------------%
+
+:- module uint64.
+:- interface.
+
+:- type placeholder_uint64 ---> placeholder_uint64.
+
diff --git a/mdbcomp/program_representation.m b/mdbcomp/program_representation.m
index 434f814..bb50d53 100644
--- a/mdbcomp/program_representation.m
+++ b/mdbcomp/program_representation.m
@@ -104,6 +104,8 @@
     ;       builtin_type_uint16_rep
     ;       builtin_type_int32_rep
     ;       builtin_type_uint32_rep
+    ;       builtin_type_int64_rep
+    ;       builtin_type_uint64_rep
     ;       builtin_type_float_rep
     ;       builtin_type_string_rep
     ;       builtin_type_char_rep.
@@ -1412,6 +1414,12 @@ read_encoded_type(ByteCode, StringTable, TypeTable, TypeRep, !Pos) :-
     ;
         Selector = 19,
         TypeRep = builtin_type_rep(builtin_type_uint32_rep)
+    ;
+        Selector = 20,
+        TypeRep = builtin_type_rep(builtin_type_int64_rep)
+    ;
+        Selector = 21,
+        TypeRep = builtin_type_rep(builtin_type_uint64_rep)
     ).
 
 %---------------------%
diff --git a/runtime/Mmakefile b/runtime/Mmakefile
index 93a4ddd..6519383 100644
--- a/runtime/Mmakefile
+++ b/runtime/Mmakefile
@@ -179,6 +179,7 @@ CFILES = \
 	mercury_heap_profile.c			\
 	mercury_hgc.c				\
 	mercury_ho_call.c			\
+	mercury_int.c				\
 	mercury_label.c				\
 	mercury_layout_util.c			\
 	mercury_memory.c			\
diff --git a/runtime/mercury.h b/runtime/mercury.h
index a4f8ee3..5346f1f 100644
--- a/runtime/mercury.h
+++ b/runtime/mercury.h
@@ -20,6 +20,7 @@
 #include "mercury_conf.h"
 #include "mercury_types.h"
 #include "mercury_float.h"              // for the `MR_Float' type
+#include "mercury_int.h"
 #include "mercury_tags.h"
 #include "mercury_grade.h"
 #include "mercury_thread.h"             // for the MR_*_GLOBAL_LOCK() macros
@@ -286,6 +287,92 @@ extern  MR_Word mercury__private_builtin__dummy_var;
     #define MR_unbox_float(B)   MR_word_to_float((MR_Word)(B))
 
   #endif // ! MR_BOXED_FLOAT
+
+#endif // MR_HIGHLEVEL_CODE
+
+////////////////////////////////////////////////////////////////////////////
+// Code to box/unbox 64-bit integers in high-level C grades.
+// The low-level C grades only use MR_{int64,uint64)_to_word and
+// MR_word_to_{int64,uint64}.
+//
+// This code is not in mercury_int.h because the function definition
+// requires the declaration of MR_new_object_atomic.
+//
+// When sizeof(int64_t) <= sizeof(MR_Box), the names "box" and "unbox" should
+// be interpreted as casts to and from MR_Box, as we do not truly box the
+// 64-bit integers then.
+
+#ifdef MR_HIGHLEVEL_CODE
+  #ifdef MR_BOXED_INT64S
+
+    #if defined(MR_GNUC)
+      #define MR_box_int64(i)                                           \
+      ({                                                                \
+          int64_t  *MR_box_int64_ptr;                                   \
+                                                                        \
+          MR_make_hp_int64_aligned();                                   \
+          MR_box_int64_ptr = (int64_t *) MR_new_object_atomic(int64_t,  \
+              sizeof(int64_t), MR_ALLOC_SITE_INT64, NULL);              \
+          *MR_box_int64_ptr = (i);                                      \
+          /* return */ (MR_Box) MR_box_int64_ptr;                       \
+      })
+    #else
+      // Note that this code is also duplicated in mercury.c.
+      MR_EXTERN_INLINE MR_Box MR_box_int64(int64_t i);
+
+      MR_EXTERN_INLINE MR_Box
+      MR_box_int64(int64_t i)
+      {
+          int64_t *ptr;
+
+          MR_make_hp_int64_aligned();
+          ptr = MR_new_object_atomic(int64_t, sizeof(int64_t),
+              MR_ALLOC_SITE_INT64, NULL);
+          *ptr = i;
+          return (MR_Box) ptr;
+      }
+    #endif
+
+    #define MR_unbox_int64(ptr) (*(int64_t *)ptr)
+
+    #if defined(MR_GNUC)
+      #define MR_box_uint64(i)                                           \
+      ({                                                                 \
+          uint64_t  *MR_box_uint64_ptr;                                  \
+                                                                         \
+          MR_make_hp_uint64_aligned();                                   \
+          MR_box_uint64_ptr = (int64_t *) MR_new_object_atomic(uint64_t, \
+              sizeof(uint64_t), MR_ALLOC_SITE_UINT64, NULL);             \
+          *MR_box_uint64_ptr = (i);                                      \
+          /* return */ (MR_Box) MR_box_uint64_ptr;                       \
+      })
+    #else
+      // Note that this code is also duplicated in mercury.c.
+      MR_EXTERN_INLINE MR_Box MR_box_uint64(uint64_t i);
+
+      MR_EXTERN_INLINE MR_Box
+      MR_box_uint64(uint64_t i)
+      {
+          uint64_t *ptr;
+
+          MR_make_hp_uint64_aligned();
+          ptr = MR_new_object_atomic(uint64_t, sizeof(uint64_t),
+              MR_ALLOC_SITE_UINT64, NULL);
+          *ptr = i;
+          return (MR_Box) ptr;
+      }
+    #endif
+
+    #define MR_unbox_uint64(ptr) (*(uint64_t *)ptr)
+
+  #else  // not MR_BOXED_INT64S
+
+    #define MR_box_int64(I)     ((MR_Box) MR_int64_to_word(I))
+    #define MR_unbox_int64(B)   MR_word_to_int64((MR_Word)(B))
+    #define MR_box_uint64(I)     ((MR_Box) MR_uint64_to_word(I))
+    #define MR_unbox_uint64(B)   MR_word_to_uint64((MR_Word)(B))
+
+  #endif // not MR_BOXED_INT64S
 #endif // MR_HIGHLEVEL_CODE
 
 ////////////////////////////////////////////////////////////////////////////
diff --git a/runtime/mercury_builtin_types.c b/runtime/mercury_builtin_types.c
index 3f56bf7..a01a743 100644
--- a/runtime/mercury_builtin_types.c
+++ b/runtime/mercury_builtin_types.c
@@ -46,6 +46,8 @@ MR_DEFINE_TYPE_CTOR_INFO(builtin, int16, 0, INT16);
 MR_DEFINE_TYPE_CTOR_INFO(builtin, uint16, 0, UINT16);
 MR_DEFINE_TYPE_CTOR_INFO(builtin, int32, 0, INT32);
 MR_DEFINE_TYPE_CTOR_INFO(builtin, uint32, 0, UINT32);
+MR_DEFINE_TYPE_CTOR_INFO(builtin, int64, 0, INT64);
+MR_DEFINE_TYPE_CTOR_INFO(builtin, uint64, 0, UINT64);
 MR_DEFINE_TYPE_CTOR_INFO(builtin, character, 0, CHAR);
 MR_DEFINE_TYPE_CTOR_INFO(builtin, string, 0, STRING);
 MR_DEFINE_TYPE_CTOR_INFO(builtin, float, 0, FLOAT);
@@ -154,6 +156,18 @@ mercury__builtin____Unify____uint32_0_0(uint32_t x, uint32_t y)
 {
     return x == y;
 }
+ 
+MR_bool MR_CALL
+mercury__builtin____Unify____int64_0_0(int64_t x, int64_t y)
+{
+    return x == y;
+}
+
+MR_bool MR_CALL
+mercury__builtin____Unify____uint64_0_0(uint64_t x, uint64_t y)
+{
+    return x == y;
+}
 
 MR_bool MR_CALL
 mercury__builtin____Unify____string_0_0(MR_String x, MR_String y)
@@ -359,6 +373,24 @@ mercury__builtin____Compare____uint32_0_0(
           x == y ? MR_COMPARE_EQUAL :
           MR_COMPARE_LESS);
 }
+ 
+void MR_CALL
+mercury__builtin____Compare____int64_0_0(
+    MR_Comparison_Result *result, int64_t x, int64_t y)
+{
+    *result = (x > y ? MR_COMPARE_GREATER :
+          x == y ? MR_COMPARE_EQUAL :
+          MR_COMPARE_LESS);
+}
+
+void MR_CALL
+mercury__builtin____Compare____uint64_0_0(
+    MR_Comparison_Result *result, uint64_t x, uint64_t y)
+{
+    *result = (x > y ? MR_COMPARE_GREATER :
+          x == y ? MR_COMPARE_EQUAL :
+          MR_COMPARE_LESS);
+}
 
 void MR_CALL
 mercury__builtin____Compare____string_0_0(MR_Comparison_Result *result,
@@ -565,6 +597,20 @@ mercury__builtin__do_unify__uint32_0_0(MR_Box x, MR_Box y)
 }
 
 MR_bool MR_CALL
+mercury__builtin__do_unify__int64_0_0(MR_Box x, MR_Box y)
+{
+    return mercury__builtin____Unify____int64_0_0(
+        MR_unbox_int64(x), MR_unbox_int64(y));
+}
+
+MR_bool MR_CALL
+mercury__builtin__do_unify__uint64_0_0(MR_Box x, MR_Box y)
+{
+    return mercury__builtin____Unify____uint64_0_0(
+        MR_unbox_uint64(x), MR_unbox_uint64(y));
+}
+ 
+MR_bool MR_CALL
 mercury__builtin__do_unify__string_0_0(MR_Box x, MR_Box y)
 {
     return mercury__builtin____Unify____string_0_0(
@@ -760,6 +806,22 @@ mercury__builtin__do_compare__uint32_0_0(
     mercury__builtin____Compare____uint32_0_0(result,
         (uint32_t) (MR_Word) x, (uint32_t) (MR_Word) y);
 }
+ 
+void MR_CALL
+mercury__builtin__do_compare__int64_0_0(
+    MR_Comparison_Result *result, MR_Box x, MR_Box y)
+{
+    mercury__builtin____Compare____int64_0_0(result,
+       MR_unbox_int64(x), MR_unbox_int64(y));
+}
+
+void MR_CALL
+mercury__builtin__do_compare__uint64_0_0(
+    MR_Comparison_Result *result, MR_Box x, MR_Box y)
+{
+    mercury__builtin____Compare____uint64_0_0(result,
+        MR_unbox_uint64(x), MR_unbox_uint64(y));
+}
 
 void MR_CALL
 mercury__builtin__do_compare__string_0_0(
@@ -953,6 +1015,8 @@ MR_UNIFY_COMPARE_REP_DECLS(builtin, int16, 0)
 MR_UNIFY_COMPARE_REP_DECLS(builtin, uint16, 0)
 MR_UNIFY_COMPARE_REP_DECLS(builtin, int32, 0)
 MR_UNIFY_COMPARE_REP_DECLS(builtin, uint32, 0)
+MR_UNIFY_COMPARE_REP_DECLS(builtin, int64, 0)
+MR_UNIFY_COMPARE_REP_DECLS(builtin, uint64, 0)
 MR_UNIFY_COMPARE_REP_DECLS(builtin, string, 0)
 MR_UNIFY_COMPARE_REP_DECLS(builtin, float, 0)
 MR_UNIFY_COMPARE_REP_DECLS(builtin, character, 0)
@@ -989,6 +1053,8 @@ MR_UNIFY_COMPARE_REP_DEFNS(builtin, int16, 0)
 MR_UNIFY_COMPARE_REP_DEFNS(builtin, uint16, 0)
 MR_UNIFY_COMPARE_REP_DEFNS(builtin, int32, 0)
 MR_UNIFY_COMPARE_REP_DEFNS(builtin, uint32, 0)
+MR_UNIFY_COMPARE_REP_DEFNS(builtin, int64, 0)
+MR_UNIFY_COMPARE_REP_DEFNS(builtin, uint64, 0)
 MR_UNIFY_COMPARE_REP_DEFNS(builtin, string, 0)
 MR_UNIFY_COMPARE_REP_DEFNS(builtin, float, 0)
 MR_UNIFY_COMPARE_REP_DEFNS(builtin, character, 0)
@@ -1068,6 +1134,8 @@ MR_DEFINE_PROC_STATIC_LAYOUTS(builtin, int16, 0);
 MR_DEFINE_PROC_STATIC_LAYOUTS(builtin, uint16, 0);
 MR_DEFINE_PROC_STATIC_LAYOUTS(builtin, int32, 0);
 MR_DEFINE_PROC_STATIC_LAYOUTS(builtin, uint32, 0);
+MR_DEFINE_PROC_STATIC_LAYOUTS(builtin, int64, 0);
+MR_DEFINE_PROC_STATIC_LAYOUTS(builtin, uint64, 0);
 MR_DEFINE_PROC_STATIC_LAYOUTS(builtin, string, 0);
 MR_DEFINE_PROC_STATIC_LAYOUTS(builtin, float, 0);
 MR_DEFINE_PROC_STATIC_LAYOUTS(builtin, character, 0);
@@ -1107,6 +1175,8 @@ MR_BEGIN_MODULE(mercury_builtin_types)
     MR_UNIFY_COMPARE_REP_LABELS(builtin, uint16, 0)
     MR_UNIFY_COMPARE_REP_LABELS(builtin, int32, 0)
     MR_UNIFY_COMPARE_REP_LABELS(builtin, uint32, 0)
+    MR_UNIFY_COMPARE_REP_LABELS(builtin, int64, 0)
+    MR_UNIFY_COMPARE_REP_LABELS(builtin, uint64, 0)
     MR_UNIFY_COMPARE_REP_LABELS(builtin, string, 0)
     MR_UNIFY_COMPARE_REP_LABELS(builtin, float, 0)
     MR_UNIFY_COMPARE_REP_LABELS(builtin, character, 0)
@@ -1303,6 +1373,48 @@ MR_BEGIN_CODE
 #undef  arity
 #undef  unify_code
 #undef  compare_code
+ 
+////////////////////////////////////////////////////////////////////////////
+ 
+#define module          builtin
+#define type            int64
+#define arity           0
+#define unify_code      MR_r1 = (MR_word_to_int64(MR_r1)                \
+                            == MR_word_to_int64(MR_r2));
+#define compare_code    int64_t i1 = MR_word_to_int64(MR_r1);           \
+                        int64_t i2 = MR_word_to_int64(MR_r2);           \
+                        MR_r1 = ((i1 > i2) ? MR_COMPARE_GREATER :       \
+                            (i1 < i2) ? MR_COMPARE_LESS :               \
+                            MR_COMPARE_EQUAL);
+
+#include "mercury_hand_unify_compare_body.h"
+
+#undef  module
+#undef  type
+#undef  arity
+#undef  unify_code
+#undef  compare_code
+
+////////////////////////////////////////////////////////////////////////////
+
+#define module          builtin
+#define type            uint64
+#define arity           0
+#define unify_code      MR_r1 = (MR_word_to_uint64(MR_r1)               \
+                            == MR_word_to_uint64(MR_r2));
+#define compare_code    uint64_t i1 = MR_word_to_uint64(MR_r1);         \
+                        uint64_t i2 = MR_word_to_uint64(MR_r2);         \
+                        MR_r1 = ((i1 > i2) ? MR_COMPARE_GREATER :       \
+                            (i1 < i2) ? MR_COMPARE_LESS :               \
+                            MR_COMPARE_EQUAL);
+
+#include "mercury_hand_unify_compare_body.h"
+
+#undef  module
+#undef  type
+#undef  arity
+#undef  unify_code
+#undef  compare_code
 
 ////////////////////////////////////////////////////////////////////////////
 
@@ -1945,6 +2057,8 @@ mercury_sys_init_mercury_builtin_types_init(void)
     MR_init_entry(mercury__builtin____Unify____uint16_0_0);
     MR_init_entry(mercury__builtin____Unify____int32_0_0);
     MR_init_entry(mercury__builtin____Unify____uint32_0_0);
+    MR_init_entry(mercury__builtin____Unify____int64_0_0);
+    MR_init_entry(mercury__builtin____Unify____uint64_0_0);
     MR_init_entry(mercury__builtin____Unify____string_0_0);
     MR_init_entry(mercury__builtin____Unify____float_0_0);
     MR_init_entry(mercury__builtin____Unify____character_0_0);
@@ -1961,6 +2075,8 @@ mercury_sys_init_mercury_builtin_types_init(void)
     MR_init_entry(mercury__builtin____Compare____uint16_0_0);
     MR_init_entry(mercury__builtin____Compare____int32_0_0);
     MR_init_entry(mercury__builtin____Compare____uint32_0_0);
+    MR_init_entry(mercury__builtin____Compare____int64_0_0);
+    MR_init_entry(mercury__builtin____Compare____uint64_0_0);
     MR_init_entry(mercury__builtin____Compare____float_0_0);
     MR_init_entry(mercury__builtin____Compare____string_0_0);
     MR_init_entry(mercury__builtin____Compare____character_0_0);
@@ -1983,6 +2099,8 @@ mercury_sys_init_mercury_builtin_types_init(void)
     MR_INIT_TYPE_CTOR_INFO_MNA(builtin, uint16, 0);
     MR_INIT_TYPE_CTOR_INFO_MNA(builtin, int32, 0);
     MR_INIT_TYPE_CTOR_INFO_MNA(builtin, uint32, 0);
+    MR_INIT_TYPE_CTOR_INFO_MNA(builtin, int64, 0);
+    MR_INIT_TYPE_CTOR_INFO_MNA(builtin, uint64, 0);
     MR_INIT_TYPE_CTOR_INFO_MNA(builtin, string, 0);
     MR_INIT_TYPE_CTOR_INFO_MNA(builtin, float, 0);
     MR_INIT_TYPE_CTOR_INFO_MNA(builtin, character, 0);
@@ -2023,6 +2141,8 @@ mercury_sys_init_mercury_builtin_types_init_type_tables(void)
     MR_REGISTER_TYPE_CTOR_INFO(builtin, uint16, 0);
     MR_REGISTER_TYPE_CTOR_INFO(builtin, int32, 0);
     MR_REGISTER_TYPE_CTOR_INFO(builtin, uint32, 0);
+    MR_REGISTER_TYPE_CTOR_INFO(builtin, int64, 0);
+    MR_REGISTER_TYPE_CTOR_INFO(builtin, uint64, 0);
     MR_REGISTER_TYPE_CTOR_INFO(builtin, string, 0);
     MR_REGISTER_TYPE_CTOR_INFO(builtin, float, 0);
     MR_REGISTER_TYPE_CTOR_INFO(builtin, character, 0);
@@ -2065,6 +2185,8 @@ mercury_sys_init_mercury_builtin_types_write_out_proc_statics(FILE *deep_fp,
     MR_WRITE_OUT_PROC_STATIC_LAYOUTS(deep_fp, builtin, uint16, 0);
     MR_WRITE_OUT_PROC_STATIC_LAYOUTS(deep_fp, builtin, int32, 0);
     MR_WRITE_OUT_PROC_STATIC_LAYOUTS(deep_fp, builtin, uint32, 0);
+    MR_WRITE_OUT_PROC_STATIC_LAYOUTS(deep_fp, builtin, int64, 0);
+    MR_WRITE_OUT_PROC_STATIC_LAYOUTS(deep_fp, builtin, uint64, 0);
     MR_WRITE_OUT_PROC_STATIC_LAYOUTS(deep_fp, builtin, string, 0);
     MR_WRITE_OUT_PROC_STATIC_LAYOUTS(deep_fp, builtin, float, 0);
     MR_WRITE_OUT_PROC_STATIC_LAYOUTS(deep_fp, builtin, character, 0);
diff --git a/runtime/mercury_builtin_types.h b/runtime/mercury_builtin_types.h
index 6dfe071..8d06d88 100644
--- a/runtime/mercury_builtin_types.h
+++ b/runtime/mercury_builtin_types.h
@@ -38,6 +38,10 @@ MR_DECLARE_TYPE_CTOR_INFO_STRUCT(
 MR_DECLARE_TYPE_CTOR_INFO_STRUCT(
     MR_TYPE_CTOR_INFO_NAME(builtin, uint32, 0));
 MR_DECLARE_TYPE_CTOR_INFO_STRUCT(
+    MR_TYPE_CTOR_INFO_NAME(builtin, int64, 0));
+MR_DECLARE_TYPE_CTOR_INFO_STRUCT(
+    MR_TYPE_CTOR_INFO_NAME(builtin, uint64, 0));
+MR_DECLARE_TYPE_CTOR_INFO_STRUCT(
     MR_TYPE_CTOR_INFO_NAME(builtin, string, 0));
 MR_DECLARE_TYPE_CTOR_INFO_STRUCT(
     MR_TYPE_CTOR_INFO_NAME(builtin, float, 0));
@@ -95,6 +99,10 @@ MR_bool MR_CALL mercury__builtin____Unify____int32_0_0(int32_t x,
                     int32_t y);
 MR_bool MR_CALL mercury__builtin____Unify____uint32_0_0(uint32_t x,
                     uint32_t y);
+MR_bool MR_CALL mercury__builtin____Unify____int64_0_0(int64_t x,
+                    int64_t y);
+MR_bool MR_CALL mercury__builtin____Unify____uint64_0_0(uint64_t x,
+                    uint64_t y);
 MR_bool MR_CALL mercury__builtin____Unify____string_0_0(MR_String x,
                     MR_String y);
 MR_bool MR_CALL mercury__builtin____Unify____float_0_0(MR_Float x, MR_Float y);
@@ -142,6 +150,10 @@ void MR_CALL    mercury__builtin____Compare____int32_0_0(
                     MR_Comparison_Result *result, int32_t x, int32_t y);
 void MR_CALL    mercury__builtin____Compare____uint32_0_0(
                     MR_Comparison_Result *result, uint32_t x, uint32_t y);
+void MR_CALL    mercury__builtin____Compare____int64_0_0(
+                    MR_Comparison_Result *result, int64_t x, int64_t y);
+void MR_CALL    mercury__builtin____Compare____uint64_0_0(
+                    MR_Comparison_Result *result, uint64_t x, uint64_t y);
 void MR_CALL    mercury__builtin____Compare____string_0_0(
                     MR_Comparison_Result *result, MR_String x, MR_String y);
 void MR_CALL    mercury__builtin____Compare____float_0_0(
diff --git a/runtime/mercury_builtin_types_proc_layouts.h b/runtime/mercury_builtin_types_proc_layouts.h
index 3b30bf7..fbc0ebf 100644
--- a/runtime/mercury_builtin_types_proc_layouts.h
+++ b/runtime/mercury_builtin_types_proc_layouts.h
@@ -44,6 +44,8 @@ MR_DECLARE_UCI_PROC_STATIC_LAYOUTS(builtin, int16, 0);
 MR_DECLARE_UCI_PROC_STATIC_LAYOUTS(builtin, uint16, 0);
 MR_DECLARE_UCI_PROC_STATIC_LAYOUTS(builtin, int32, 0);
 MR_DECLARE_UCI_PROC_STATIC_LAYOUTS(builtin, uint32, 0);
+MR_DECLARE_UCI_PROC_STATIC_LAYOUTS(builtin, int64, 0);
+MR_DECLARE_UCI_PROC_STATIC_LAYOUTS(builtin, uint64, 0);
 MR_DECLARE_UCI_PROC_STATIC_LAYOUTS(builtin, string, 0);
 MR_DECLARE_UCI_PROC_STATIC_LAYOUTS(builtin, float, 0);
 MR_DECLARE_UCI_PROC_STATIC_LAYOUTS(builtin, character, 0);
diff --git a/runtime/mercury_conf.h.in b/runtime/mercury_conf.h.in
index b59cefc..a6e894d 100644
--- a/runtime/mercury_conf.h.in
+++ b/runtime/mercury_conf.h.in
@@ -104,6 +104,11 @@
 
 #undef  MR_BOXED_FLOAT
 
+// MR_BOXED_INT64S: defined if int64_t and uint64_t is wider than a MR_Word,
+// i.e. on 32-bit architectures.
+
+#undef  MR_BOXED_INT64S
+
 // The following macros are defined iff the corresponding header file
 // is available:
 //
diff --git a/runtime/mercury_construct.c b/runtime/mercury_construct.c
index b47187f..d9ddc17 100644
--- a/runtime/mercury_construct.c
+++ b/runtime/mercury_construct.c
@@ -166,6 +166,8 @@ MR_get_functor_info(MR_TypeInfo type_info, int functor_number,
     case MR_TYPECTOR_REP_UINT16:
     case MR_TYPECTOR_REP_INT32:
     case MR_TYPECTOR_REP_UINT32:
+    case MR_TYPECTOR_REP_INT64:
+    case MR_TYPECTOR_REP_UINT64:
     case MR_TYPECTOR_REP_CHAR:
     case MR_TYPECTOR_REP_FLOAT:
     case MR_TYPECTOR_REP_STRING:
@@ -329,6 +331,8 @@ MR_get_num_functors(MR_TypeInfo type_info)
         case MR_TYPECTOR_REP_UINT16:
         case MR_TYPECTOR_REP_INT32:
         case MR_TYPECTOR_REP_UINT32:
+        case MR_TYPECTOR_REP_INT64:
+        case MR_TYPECTOR_REP_UINT64:
         case MR_TYPECTOR_REP_CHAR:
         case MR_TYPECTOR_REP_FLOAT:
         case MR_TYPECTOR_REP_STRING:
diff --git a/runtime/mercury_deconstruct.c b/runtime/mercury_deconstruct.c
index 130aa21..e73f57d 100644
--- a/runtime/mercury_deconstruct.c
+++ b/runtime/mercury_deconstruct.c
@@ -271,6 +271,8 @@ MR_named_arg_num(MR_TypeInfo type_info, MR_Word *term_ptr,
         case MR_TYPECTOR_REP_UINT16:
         case MR_TYPECTOR_REP_INT32:
         case MR_TYPECTOR_REP_UINT32:
+        case MR_TYPECTOR_REP_INT64:
+        case MR_TYPECTOR_REP_UINT64:
         case MR_TYPECTOR_REP_FLOAT:
         case MR_TYPECTOR_REP_CHAR:
         case MR_TYPECTOR_REP_STRING:
diff --git a/runtime/mercury_deep_copy_body.h b/runtime/mercury_deep_copy_body.h
index 1876a43..f8bb023 100644
--- a/runtime/mercury_deep_copy_body.h
+++ b/runtime/mercury_deep_copy_body.h
@@ -416,6 +416,66 @@ try_again:
     case MR_TYPECTOR_REP_UINT32: // fallthru
     case MR_TYPECTOR_REP_CHAR:
         return data;
+    
+    case MR_TYPECTOR_REP_INT64:
+        #ifdef MR_BOXED_INT64S
+            {
+                MR_Word    *data_value;
+
+                assert(MR_tag(data) == 0);
+                data_value = (MR_Word *) MR_body(data, MR_mktag(0));
+
+                RETURN_IF_OUT_OF_RANGE(data, data_value, 0, MR_Word);
+
+                {
+                    MR_restore_transient_hp();
+#ifdef MR_HIGHLEVEL_CODE
+                    // We can't use MR_int64_to_word, since it uses MR_hp,
+                    // which in grade hlc.par.gc will be a reference to
+                    // thread-local storage that we haven't allocated.
+
+                    new_data = (MR_Word) MR_box_int64(MR_unbox_int64(data));
+#else
+                    new_data = MR_int64_to_word(MR_word_to_int64(data));
+#endif
+                    MR_save_transient_hp();
+                    leave_forwarding_pointer(data_value, 0, new_data);
+                }
+            }
+        #else
+            new_data = data;
+        #endif
+        return new_data;
+    
+    case MR_TYPECTOR_REP_UINT64:
+        #ifdef MR_BOXED_INT64S
+            {
+                MR_Word    *data_value;
+
+                assert(MR_tag(data) == 0);
+                data_value = (MR_Word *) MR_body(data, MR_mktag(0));
+
+                RETURN_IF_OUT_OF_RANGE(data, data_value, 0, MR_Word);
+
+                {
+                    MR_restore_transient_hp();
+#ifdef MR_HIGHLEVEL_CODE
+                    // We can't use MR_uint64_to_word, since it uses MR_hp,
+                    // which in grade hlc.par.gc will be a reference to
+                    // thread-local storage that we haven't allocated.
+
+                    new_data = (MR_Word) MR_box_uint64(MR_unbox_uint64(data));
+#else
+                    new_data = MR_uint64_to_word(MR_word_to_uint64(data));
+#endif
+                    MR_save_transient_hp();
+                    leave_forwarding_pointer(data_value, 0, new_data);
+                }
+            }
+        #else
+            new_data = data;
+        #endif
+        return new_data;
 
     case MR_TYPECTOR_REP_FLOAT:
         #ifdef MR_BOXED_FLOAT
diff --git a/runtime/mercury_dotnet.cs.in b/runtime/mercury_dotnet.cs.in
index 3162e1b..63e6c20 100644
--- a/runtime/mercury_dotnet.cs.in
+++ b/runtime/mercury_dotnet.cs.in
@@ -344,8 +344,10 @@ public enum TypeCtorRep {
     MR_TYPECTOR_REP_UINT16                  = 50,
     MR_TYPECTOR_REP_INT32                   = 51,
     MR_TYPECTOR_REP_UINT32                  = 52,
-    MR_TYPECTOR_REP_UNKNOWN                 = 53,
-    MR_TYPECTOR_REP_MAX                     = 54
+    MR_TYPECTOR_REP_INT64                   = 53,
+    MR_TYPECTOR_REP_UINT64                  = 54,
+    MR_TYPECTOR_REP_UNKNOWN                 = 55,
+    MR_TYPECTOR_REP_MAX                     = 56
 }
 
 public class PseudoTypeInfo {
diff --git a/runtime/mercury_hash_lookup_or_add_body.h b/runtime/mercury_hash_lookup_or_add_body.h
index 7f38647..d04675e 100644
--- a/runtime/mercury_hash_lookup_or_add_body.h
+++ b/runtime/mercury_hash_lookup_or_add_body.h
@@ -15,7 +15,7 @@
     MR_Integer          home;
     MR_TABLE_DECLARE_KEY_COMPARE_COUNT
 
-    debug_key_msg(key, key_format, key_cast);
+    debug_key_msg(key, "%"key_format, key_cast);
 
     // Deref the table pointer.
     table = t->MR_hash_table;
diff --git a/runtime/mercury_heap_profile.c b/runtime/mercury_heap_profile.c
index d4d068a..aa627db 100644
--- a/runtime/mercury_heap_profile.c
+++ b/runtime/mercury_heap_profile.c
@@ -243,7 +243,7 @@ static void     write_var_size_counts(FILE *fp, const char *prefix,
                     MR_VarSizeCount *node);
 static const char *maybe_filename(const char *s);
 
-#define MR_NUM_BUILTIN_ALLOC_SITES  7
+#define MR_NUM_BUILTIN_ALLOC_SITES  9
 
 MR_AllocSiteInfo MR_builtin_alloc_sites[MR_NUM_BUILTIN_ALLOC_SITES] = {
     // These must match the macros in mercury_memory.h.
@@ -253,7 +253,9 @@ MR_AllocSiteInfo MR_builtin_alloc_sites[MR_NUM_BUILTIN_ALLOC_SITES] = {
     { NULL, "unknown", 0, "type_info/0",        0 },
     { NULL, "unknown", 0, "<foreign>",          0 },
     { NULL, "unknown", 0, "<tabling structs>",  0 },
-    { NULL, "unknown", 0, "<stm structs>",      0 }
+    { NULL, "unknown", 0, "<stm structs>",      0 },
+    { NULL, "unknown", 0, "int64.int64/0",      MR_INT64_WORDS },
+    { NULL, "unknown", 0, "uint64.uint64/0",    MR_UINT64_WORDS }
 };
 
 void
diff --git a/runtime/mercury_int.c b/runtime/mercury_int.c
new file mode 100644
index 0000000..919c136
--- /dev/null
+++ b/runtime/mercury_int.c
@@ -0,0 +1,25 @@
+// vim: ts=4 sw=4 expandtab ft=c
+
+// Copyright (C) 2017 The Mercury team.
+// This file may only be copied under the terms of the GNU Library General
+// Public License - see the file COPYING.LIB in the Mercury distribution.
+
+#include "mercury_int.h"
+
+MR_Integer MR_hash_int64(int64_t i)
+{
+    if (sizeof(int64_t) <= sizeof(MR_Integer)) {
+        return (MR_Integer) i;
+    } else {
+        return (uint32_t)i ^ ((uint64_t)i >> 32);
+    }
+}
+
+MR_Integer MR_hash_uint64(uint64_t i)
+{
+    if (sizeof(uint64_t) <= sizeof(MR_Integer)) {
+        return (MR_Integer) i;
+    } else {
+        return (uint32_t)i ^ (i >> 32);
+    }
+}
diff --git a/runtime/mercury_int.h b/runtime/mercury_int.h
index 51088b7..548c2b5 100644
--- a/runtime/mercury_int.h
+++ b/runtime/mercury_int.h
@@ -9,10 +9,102 @@
 #ifndef MERCURY_INT_H
 #define MERCURY_INT_H
 
-#include "mercury_conf.h"       // for MR_BOXED_FLOAT, MR_CONSERVATIVE_GC
+#include "mercury_conf.h"       // for MR_BOXED_INT64S, MR_CONSERVATIVE_GC
 #include "mercury_types.h"      // for `MR_Word'
 #include "mercury_std.h"        // for `MR_bool'
 
+#define MR_INT64_WORDS          ((sizeof(int64_t) + sizeof(MR_Word) - 1) \
+                                        / sizeof(MR_Word))
+#define MR_UINT64_WORDS         ((sizeof(uint64_t) + sizeof(MR_Word) - 1) \
+                                        / sizeof(MR_Word))
+#if defined(MR_BOXED_INT64S)
+
+   #define MR_word_to_int64(w)   (* (int64_t *) (w))
+   #define MR_word_to_uint64(w)   (* (uint64_t *) (w))
+
+   #if defined(MR_CONSERVATIVE_GC)
+
+    #define MR_int64_to_word(i)                                             \
+      (                                                                     \
+        MR_hp_alloc_atomic_msg(MR_INT64_WORDS,                              \
+            (MR_AllocSiteInfoPtr) MR_ALLOC_SITE_INT64, NULL),               \
+        * (int64_t *) (void *) (MR_hp - MR_INT64_WORDS) = (i),              \
+        /* return */ (MR_Word) (MR_hp - MR_INT64_WORDS)                     \
+      )
+    #define MR_make_hp_int64_aligned() ((void)0)
+
+    #define MR_uint64_to_word(u)                                            \
+      (                                                                     \
+        MR_hp_alloc_atomic_msg(MR_UINT64_WORDS,                             \
+            (MR_AllocSiteInfoPtr) MR_ALLOC_SITE_UINT64, NULL),              \
+        * (uint64_t *) (void *) (MR_hp - MR_UINT64_WORDS) = (u),            \
+        /* return */ (MR_Word) (MR_hp - MR_UINT64_WORDS)                    \
+      )
+    #define MR_make_hp_uint64_aligned() ((void)0)
+
+   #else // ! defined(MR_CONSERVATIVE_GC)
+    // We need to ensure that what we allocated on the heap is properly
+    // aligned for a floating-point value, by rounding MR_hp up to the
+    // nearest int64-aligned boundary.
+    // XXX This code assumes that sizeof(int64_t) is a power of two,
+    // and not greater than 2 * sizeof(MR_Word).
+
+    #define MR_make_hp_int64_aligned()                                      \
+      ( (MR_Word) MR_hp & (sizeof(int64_t) - 1) ?                           \
+            MR_hp_alloc_atomic_msg(1, MR_ALLOC_SITE_INT64, NULL)            \
+      :                                                                     \
+            (void)0                                                         \
+      )
+    #define MR_int64_to_word(i)                                             \
+      (                                                                     \
+        MR_make_hp_int64_aligned(),                                         \
+        MR_hp_alloc_atomic_msg(MR_INT64_WORDS, MR_ALLOC_SITE_INT64, NULL),  \
+        * (int64_t *) (void *)(MR_hp - MR_INT64_WORDS) = (i),               \
+        /* return */ (MR_Word) (MR_hp - MR_INT64_WORDS)                     \
+      )
+    
+    #define MR_make_hp_uint64_aligned()                                      \
+      ( (MR_Word) MR_hp & (sizeof(uint64_t) - 1) ?                           \
+            MR_hp_alloc_atomic_msg(1, MR_ALLOC_SITE_UINT64, NULL)            \
+      :                                                                      \
+            (void)0                                                          \
+      )
+    #define MR_uint64_to_word(u)                                             \
+      (                                                                      \
+        MR_make_hp_uint64_aligned(),                                         \
+        MR_hp_alloc_atomic_msg(MR_UINT64_WORDS, MR_ALLOC_SITE_UINT64, NULL), \
+        * (uint64_t *) (void *)(MR_hp - MR_UINT64_WORDS) = (u),              \
+        /* return */ (MR_Word) (MR_hp - MR_UINT64_WORDS)                     \
+      )
+
+  #endif
+
+  #if defined(MR_GNUC)
+    #define MR_int64_const(i) ({ static const int64_t d = i; (MR_Word) &d; })
+    #define MR_uint64_const(u) ({ static const uint64_t d = u; (MR_Word) &d; })
+  #else
+    #define MR_int64_const(i) MR_int64_to_word(i)   // inefficient
+    #define MR_uint64_const(u) MR_uint64_to_word(u)   // inefficient
+  #endif
+
+#else // not MR_BOXED_INT64S
+
+  // Unboxed float means we can assume sizeof(int64_t) <= sizeof(MR_Word).
+
+  #define MR_make_hp_int64_aligned() ((void)0)
+  #define MR_make_hp_uint64_aligned() ((void)0)
+
+  #define MR_int64_const(i) MR_int64_to_word(i)
+  #define MR_uint64_const(u) MR_uint64_to_word(u)
+
+  #define MR_int64_to_word(i) ((MR_Word)(i))
+  #define MR_uint64_to_word(u) ((MR_Word)(u))
+
+#endif // not MR_BOXED_INT64S
+
+extern MR_Integer MR_hash_int64(int64_t);
+extern MR_Integer MR_hash_uint64(uint64_t);
+
 #if defined(MR_GNUC) || defined(MR_CLANG)
   #define MR_uint16_reverse_bytes(U) __builtin_bswap16((U))
 #elif defined(MR_MSVC)
diff --git a/runtime/mercury_memory.h b/runtime/mercury_memory.h
index 62e59c6..3c217b8 100644
--- a/runtime/mercury_memory.h
+++ b/runtime/mercury_memory.h
@@ -329,7 +329,7 @@ struct MR_AllocSiteInfo_Struct {
 #define MR_ALLOC_SITE_NONE      ((void *) 0)
 #ifdef MR_MPROF_PROFILE_MEMORY_ATTRIBUTION
     // These must match the entries in mercury_heap_profile.c.
-    extern MR_AllocSiteInfo         MR_builtin_alloc_sites[7];
+    extern MR_AllocSiteInfo         MR_builtin_alloc_sites[9];
     #define MR_ALLOC_SITE_RUNTIME   ((void *) &MR_builtin_alloc_sites[0])
     #define MR_ALLOC_SITE_FLOAT     ((void *) &MR_builtin_alloc_sites[1])
     #define MR_ALLOC_SITE_STRING    ((void *) &MR_builtin_alloc_sites[2])
@@ -337,6 +337,8 @@ struct MR_AllocSiteInfo_Struct {
     #define MR_ALLOC_SITE_FOREIGN   ((void *) &MR_builtin_alloc_sites[4])
     #define MR_ALLOC_SITE_TABLING   ((void *) &MR_builtin_alloc_sites[5])
     #define MR_ALLOC_SITE_STM       ((void *) &MR_builtin_alloc_sites[6])
+    #define MR_ALLOC_SITE_INT64     ((void *) &MR_builtin_alloc_sites[7])
+    #define MR_ALLOC_SITE_UINT64    ((void *) &MR_builtin_alloc_sites[8])
 #else
     #define MR_ALLOC_ID             MR_ALLOC_SITE_NONE
     #define MR_ALLOC_SITE_RUNTIME   MR_ALLOC_SITE_NONE
@@ -346,6 +348,8 @@ struct MR_AllocSiteInfo_Struct {
     #define MR_ALLOC_SITE_FOREIGN   MR_ALLOC_SITE_NONE
     #define MR_ALLOC_SITE_TABLING   MR_ALLOC_SITE_NONE
     #define MR_ALLOC_SITE_STM       MR_ALLOC_SITE_NONE
+    #define MR_ALLOC_SITE_INT64     MR_ALLOC_SITE_NONE
+    #define MR_ALLOC_SITE_UINT64    MR_ALLOC_SITE_NONE
 #endif
 
 extern  void    *MR_new_object_func(size_t num_bytes,
diff --git a/runtime/mercury_ml_expand_body.h b/runtime/mercury_ml_expand_body.h
index 0203ac2..8fbec28 100644
--- a/runtime/mercury_ml_expand_body.h
+++ b/runtime/mercury_ml_expand_body.h
@@ -115,6 +115,7 @@
 //  instead, but it is not yet safe to throw exceptions across the C interface.
 
 #include <stdio.h>
+#include <inttypes.h>
 #include "mercury_library_types.h" // for MR_ArrayType
 #include "mercury_layout_util.h"   // for MR_materialize_closure_type_params
 #include "mercury_ho_call.h"       // for MR_ClosureId etc
@@ -900,6 +901,44 @@ EXPAND_FUNCTION_NAME(MR_TypeInfo type_info, MR_Word *data_word_ptr,
 
             handle_zero_arity_args();
             return;
+        
+        case MR_TYPECTOR_REP_INT64:
+#ifdef  EXPAND_FUNCTOR_FIELD
+            {
+                MR_Word data_word;
+                char    buf[500];
+                int64_t i64;
+                char    *str;
+
+                data_word = *data_word_ptr;
+                i64 = MR_word_to_int64(data_word);
+                sprintf(buf, "%" PRIx64 "i64", i64);
+                MR_make_aligned_string_copy_saved_hp(str, buf, NULL);
+                expand_info->EXPAND_FUNCTOR_FIELD = str;
+            }
+#endif  // EXPAND_FUNCTOR_FIELD
+
+            handle_zero_arity_args();
+            return;
+        
+        case MR_TYPECTOR_REP_UINT64:
+#ifdef  EXPAND_FUNCTOR_FIELD
+            {
+                MR_Word     data_word;
+                char        buf[500];
+                uint64_t    u64;
+                char        *str;
+
+                data_word = *data_word_ptr;
+                u64 = MR_word_to_uint64(data_word);
+                sprintf(buf, "%" PRIu64 "u64", u64);
+                MR_make_aligned_string_copy_saved_hp(str, buf, NULL);
+                expand_info->EXPAND_FUNCTOR_FIELD = str;
+            }
+#endif  // EXPAND_FUNCTOR_FIELD
+
+            handle_zero_arity_args();
+            return;
 
         case MR_TYPECTOR_REP_CHAR:
 #ifdef  EXPAND_FUNCTOR_FIELD
diff --git a/runtime/mercury_table_type_body.h b/runtime/mercury_table_type_body.h
index bf1883c..5b8f4c4 100644
--- a/runtime/mercury_table_type_body.h
+++ b/runtime/mercury_table_type_body.h
@@ -336,6 +336,16 @@
             MR_TABLE_UINT32(STATS, DEBUG, BACK, table_next, table, data);
             table = table_next;
             return table;
+        
+        case MR_TYPECTOR_REP_INT64:
+            MR_TABLE_INT64(STATS, DEBUG, BACK, table_next, table, data);
+            table = table_next;
+            return table;
+
+        case MR_TYPECTOR_REP_UINT64:
+            MR_TABLE_UINT64(STATS, DEBUG, BACK, table_next, table, data);
+            table = table_next;
+            return table;
 
         case MR_TYPECTOR_REP_CHAR:
             MR_TABLE_CHAR(STATS, DEBUG, BACK, table_next, table, data);
diff --git a/runtime/mercury_tabling.c b/runtime/mercury_tabling.c
index 5175a36..a13c3bb 100644
--- a/runtime/mercury_tabling.c
+++ b/runtime/mercury_tabling.c
@@ -40,9 +40,11 @@ static  void    MR_table_assert_failed(const char *file, unsigned line);
 // the same.
 
 typedef struct MR_IntHashTableSlot_Struct       MR_IntHashTableSlot;
+typedef struct MR_Int64HashTableSlot_Struct     MR_Int64HashTableSlot;
+typedef struct MR_UInt64HashTableSlot_Struct    MR_UInt64HashTableSlot;
 typedef struct MR_FloatHashTableSlot_Struct     MR_FloatHashTableSlot;
 typedef struct MR_StringHashTableSlot_Struct    MR_StringHashTableSlot;
-typedef struct MR_BitmapHashTableSlot_Struct MR_BitmapHashTableSlot;
+typedef struct MR_BitmapHashTableSlot_Struct    MR_BitmapHashTableSlot;
 typedef struct MR_WordHashTableSlot_Struct      MR_WordHashTableSlot;
 
 typedef struct MR_AllocRecord_Struct            MR_AllocRecord;
@@ -59,6 +61,18 @@ struct MR_FloatHashTableSlot_Struct {
     MR_Float                key;
 };
 
+struct MR_Int64HashTableSlot_Struct {
+    MR_Int64HashTableSlot   *next;
+    MR_TableNode            data;
+    int64_t                 key;
+};
+
+struct MR_UInt64HashTableSlot_Struct {
+    MR_UInt64HashTableSlot  *next;
+    MR_TableNode            data;
+    uint64_t                key;
+};
+
 struct MR_StringHashTableSlot_Struct {
     MR_StringHashTableSlot  *next;
     MR_TableNode            data;
@@ -79,6 +93,8 @@ struct MR_WordHashTableSlot_Struct {
 
 typedef union {
     MR_IntHashTableSlot     *int_slot_ptr;
+    MR_Int64HashTableSlot   *int64_slot_ptr;
+    MR_UInt64HashTableSlot  *uint64_slot_ptr;
     MR_FloatHashTableSlot   *float_slot_ptr;
     MR_StringHashTableSlot  *string_slot_ptr;
     MR_BitmapHashTableSlot  *bitmap_slot_ptr;
@@ -307,7 +323,7 @@ next_prime(MR_Integer old_size)
 MR_TrieNode
 MR_int_hash_lookup_or_add(MR_TrieNode t, MR_Integer key)
 {
-#define key_format              "%ld"
+#define key_format              "ld"
 #define key_cast                long
 #define table_type              MR_IntHashTableSlot
 #define table_field             int_slot_ptr
@@ -330,7 +346,7 @@ MR_TrieNode
 MR_int_hash_lookup_or_add_stats(MR_TableStepStats *stats,
     MR_TrieNode t, MR_Integer key)
 {
-#define key_format              "%ld"
+#define key_format              "ld"
 #define key_cast                long
 #define table_type              MR_IntHashTableSlot
 #define table_field             int_slot_ptr
@@ -352,7 +368,7 @@ MR_int_hash_lookup_or_add_stats(MR_TableStepStats *stats,
 MR_TrieNode
 MR_int_hash_lookup(MR_TrieNode t, MR_Integer key)
 {
-#define key_format              "%ld"
+#define key_format              "ld"
 #define key_cast                long
 #define table_type              MR_IntHashTableSlot
 #define table_field             int_slot_ptr
@@ -371,6 +387,140 @@ MR_int_hash_lookup(MR_TrieNode t, MR_Integer key)
 #undef  lookup_only
 }
 
+MR_TrieNode
+MR_int64_hash_lookup_or_add(MR_TrieNode t, int64_t key)
+{
+#define key_format              PRIx64
+#define key_cast                int64_t
+#define table_type              MR_Int64HashTableSlot
+#define table_field             int64_slot_ptr
+#define hash(key)               (MR_hash_int64(key))
+#define equal_keys(k1, k2)      ((k1) == (k2))
+#define lookup_only             MR_FALSE
+#include "mercury_tabling_stats_nodefs.h"
+#include "mercury_hash_lookup_or_add_body.h"
+#include "mercury_tabling_stats_undefs.h"
+#undef  key_format
+#undef  key_cast
+#undef  table_type
+#undef  table_field
+#undef  hash
+#undef  equal_keys
+#undef  lookup_only
+}
+
+MR_TrieNode
+MR_int64_hash_lookup_or_add_stats(MR_TableStepStats *stats,
+    MR_TrieNode t, int64_t key)
+{
+#define key_format              PRIx64
+#define key_cast                int64_t 
+#define table_type              MR_Int64HashTableSlot
+#define table_field             int64_slot_ptr
+#define hash(key)               (MR_hash_int64(key))
+#define equal_keys(k1, k2)      ((k1) == (k2))
+#define lookup_only             MR_FALSE
+#include "mercury_tabling_stats_defs.h"
+#include "mercury_hash_lookup_or_add_body.h"
+#include "mercury_tabling_stats_undefs.h"
+#undef  key_format
+#undef  key_cast
+#undef  table_type
+#undef  table_field
+#undef  hash
+#undef  equal_keys
+#undef  lookup_only
+}
+
+MR_TrieNode
+MR_int64_hash_lookup(MR_TrieNode t, int64_t key)
+{
+#define key_format              PRIx64
+#define key_cast                int64_t 
+#define table_type              MR_Int64HashTableSlot
+#define table_field             int64_slot_ptr
+#define hash(key)               (MR_hash_int64(key))
+#define equal_keys(k1, k2)      ((k1) == (k2))
+#define lookup_only             MR_TRUE
+#include "mercury_tabling_stats_nodefs.h"
+#include "mercury_hash_lookup_or_add_body.h"
+#include "mercury_tabling_stats_undefs.h"
+#undef  key_format
+#undef  key_cast
+#undef  table_type
+#undef  table_field
+#undef  hash
+#undef  equal_keys
+#undef  lookup_only
+}
+
+MR_TrieNode
+MR_uint64_hash_lookup_or_add(MR_TrieNode t, uint64_t key)
+{
+#define key_format              PRIu64
+#define key_cast                uint64_t
+#define table_type              MR_UInt64HashTableSlot
+#define table_field             uint64_slot_ptr
+#define hash(key)               (MR_hash_uint64(key))
+#define equal_keys(k1, k2)      ((k1) == (k2))
+#define lookup_only             MR_FALSE
+#include "mercury_tabling_stats_nodefs.h"
+#include "mercury_hash_lookup_or_add_body.h"
+#include "mercury_tabling_stats_undefs.h"
+#undef  key_format
+#undef  key_cast
+#undef  table_type
+#undef  table_field
+#undef  hash
+#undef  equal_keys
+#undef  lookup_only
+}
+
+MR_TrieNode
+MR_uint64_hash_lookup_or_add_stats(MR_TableStepStats *stats,
+    MR_TrieNode t, uint64_t key)
+{
+#define key_format              PRIu64
+#define key_cast                uint64_t 
+#define table_type              MR_UInt64HashTableSlot
+#define table_field             uint64_slot_ptr
+#define hash(key)               (MR_hash_uint64(key))
+#define equal_keys(k1, k2)      ((k1) == (k2))
+#define lookup_only             MR_FALSE
+#include "mercury_tabling_stats_defs.h"
+#include "mercury_hash_lookup_or_add_body.h"
+#include "mercury_tabling_stats_undefs.h"
+#undef  key_format
+#undef  key_cast
+#undef  table_type
+#undef  table_field
+#undef  hash
+#undef  equal_keys
+#undef  lookup_only
+}
+
+MR_TrieNode
+MR_uint64_hash_lookup(MR_TrieNode t, uint64_t key)
+{
+#define key_format              PRIu64
+#define key_cast                uint64_t 
+#define table_type              MR_UInt64HashTableSlot
+#define table_field             uint64_slot_ptr
+#define hash(key)               (MR_hash_uint64(key))
+#define equal_keys(k1, k2)      ((k1) == (k2))
+#define lookup_only             MR_TRUE
+#include "mercury_tabling_stats_nodefs.h"
+#include "mercury_hash_lookup_or_add_body.h"
+#include "mercury_tabling_stats_undefs.h"
+#undef  key_format
+#undef  key_cast
+#undef  table_type
+#undef  table_field
+#undef  hash
+#undef  equal_keys
+#undef  lookup_only
+}
+
 // Note that the equal_keys operation should compare two floats for
 // bit-for-bit equality. This is different from the usual == operator
 // in the presence of NaNs, infinities, etc.
@@ -378,7 +528,7 @@ MR_int_hash_lookup(MR_TrieNode t, MR_Integer key)
 MR_TrieNode
 MR_float_hash_lookup_or_add(MR_TrieNode t, MR_Float key)
 {
-#define key_format              "%f"
+#define key_format              "f"
 #define key_cast                double
 #define table_type              MR_FloatHashTableSlot
 #define table_field             float_slot_ptr
@@ -401,7 +551,7 @@ MR_TrieNode
 MR_float_hash_lookup_or_add_stats(MR_TableStepStats *stats,
     MR_TrieNode t, MR_Float key)
 {
-#define key_format              "%f"
+#define key_format              "f"
 #define key_cast                double
 #define table_type              MR_FloatHashTableSlot
 #define table_field             float_slot_ptr
@@ -423,7 +573,7 @@ MR_float_hash_lookup_or_add_stats(MR_TableStepStats *stats,
 MR_TrieNode
 MR_float_hash_lookup(MR_TrieNode t, MR_Float key)
 {
-#define key_format              "%f"
+#define key_format              "f"
 #define key_cast                double
 #define table_type              MR_FloatHashTableSlot
 #define table_field             float_slot_ptr
@@ -445,7 +595,7 @@ MR_float_hash_lookup(MR_TrieNode t, MR_Float key)
 MR_TrieNode
 MR_string_hash_lookup_or_add(MR_TrieNode t, MR_ConstString key)
 {
-#define key_format              "%s"
+#define key_format              "s"
 #define key_cast                const char *
 #define table_type              MR_StringHashTableSlot
 #define table_field             string_slot_ptr
@@ -468,7 +618,7 @@ MR_TrieNode
 MR_string_hash_lookup_or_add_stats(MR_TableStepStats *stats,
     MR_TrieNode t, MR_ConstString key)
 {
-#define key_format              "%s"
+#define key_format              "s"
 #define key_cast                const char *
 #define table_type              MR_StringHashTableSlot
 #define table_field             string_slot_ptr
@@ -490,7 +640,7 @@ MR_string_hash_lookup_or_add_stats(MR_TableStepStats *stats,
 MR_TrieNode
 MR_string_hash_lookup(MR_TrieNode t, MR_ConstString key)
 {
-#define key_format              "%s"
+#define key_format              "s"
 #define key_cast                const char *
 #define table_type              MR_StringHashTableSlot
 #define table_field             string_slot_ptr
@@ -512,7 +662,7 @@ MR_string_hash_lookup(MR_TrieNode t, MR_ConstString key)
 MR_TrieNode
 MR_bitmap_hash_lookup_or_add(MR_TrieNode t, MR_ConstBitmapPtr key)
 {
-#define key_format              "%d"
+#define key_format              "d"
 #define key_cast                void *
 #define table_type              MR_BitmapHashTableSlot
 #define table_field             bitmap_slot_ptr
@@ -535,7 +685,7 @@ MR_TrieNode
 MR_bitmap_hash_lookup_or_add_stats(MR_TableStepStats *stats,
     MR_TrieNode t, MR_ConstBitmapPtr key)
 {
-#define key_format              "%d"
+#define key_format              "d"
 #define key_cast                MR_Word
 #define table_type              MR_BitmapHashTableSlot
 #define table_field             bitmap_slot_ptr
@@ -557,7 +707,7 @@ MR_bitmap_hash_lookup_or_add_stats(MR_TableStepStats *stats,
 MR_TrieNode
 MR_bitmap_hash_lookup(MR_TrieNode t, MR_ConstBitmapPtr key)
 {
-#define key_format              "%d"
+#define key_format              "d"
 #define key_cast                MR_Word
 #define table_type              MR_BitmapHashTableSlot
 #define table_field             bitmap_slot_ptr
@@ -579,7 +729,7 @@ MR_bitmap_hash_lookup(MR_TrieNode t, MR_ConstBitmapPtr key)
 MR_TrieNode
 MR_word_hash_lookup_or_add(MR_TrieNode t, MR_Word key)
 {
-#define key_format              "%d"
+#define key_format              "d"
 #define key_cast                MR_Word
 #define table_type              MR_WordHashTableSlot
 #define table_field             word_slot_ptr
@@ -602,7 +752,7 @@ MR_TrieNode
 MR_word_hash_lookup_or_add_stats(MR_TableStepStats *stats,
     MR_TrieNode t, MR_Word key)
 {
-#define key_format              "%d"
+#define key_format              "d"
 #define key_cast                MR_Word
 #define table_type              MR_WordHashTableSlot
 #define table_field             word_slot_ptr
@@ -624,7 +774,7 @@ MR_word_hash_lookup_or_add_stats(MR_TableStepStats *stats,
 MR_TrieNode
 MR_word_hash_lookup(MR_TrieNode t, MR_Word key)
 {
-#define key_format              "%d"
+#define key_format              "d"
 #define key_cast                MR_Word
 #define table_type              MR_WordHashTableSlot
 #define table_field             word_slot_ptr
diff --git a/runtime/mercury_tabling.h b/runtime/mercury_tabling.h
index 32fb110..2898ccd 100644
--- a/runtime/mercury_tabling.h
+++ b/runtime/mercury_tabling.h
@@ -256,7 +256,9 @@ typedef enum {
     MR_DEFINE_BUILTIN_ENUM_CONST(MR_TABLE_STEP_INT16),
     MR_DEFINE_BUILTIN_ENUM_CONST(MR_TABLE_STEP_UINT16),
     MR_DEFINE_BUILTIN_ENUM_CONST(MR_TABLE_STEP_INT32),
-    MR_DEFINE_BUILTIN_ENUM_CONST(MR_TABLE_STEP_UINT32)
+    MR_DEFINE_BUILTIN_ENUM_CONST(MR_TABLE_STEP_UINT32),
+    MR_DEFINE_BUILTIN_ENUM_CONST(MR_TABLE_STEP_INT64),
+    MR_DEFINE_BUILTIN_ENUM_CONST(MR_TABLE_STEP_UINT64)
 } MR_TableTrieStep;
 
 typedef MR_Unsigned MR_Counter;
@@ -374,6 +376,16 @@ extern  MR_TrieNode MR_int_hash_lookup_or_add(MR_TrieNode table,
 extern  MR_TrieNode MR_int_hash_lookup_or_add_stats(
                         MR_TableStepStats *stats, MR_TrieNode table,
                         MR_Integer key);
+extern  MR_TrieNode MR_int64_hash_lookup_or_add(MR_TrieNode table,
+                        int64_t key);
+extern  MR_TrieNode MR_int64_hash_lookup_or_add_stats(
+                        MR_TableStepStats *stats, MR_TrieNode table,
+                        int64_t key);
+extern  MR_TrieNode MR_uint64_hash_lookup_or_add(MR_TrieNode table,
+                        uint64_t key);
+extern  MR_TrieNode MR_uint64_hash_lookup_or_add_stats(
+                        MR_TableStepStats *stats, MR_TrieNode table,
+                        uint64_t key);
 extern  MR_TrieNode MR_float_hash_lookup_or_add(MR_TrieNode table,
                         MR_Float key);
 extern  MR_TrieNode MR_float_hash_lookup_or_add_stats(
@@ -470,6 +482,10 @@ extern  MR_TrieNode MR_table_type_stats_debug_back(MR_TableStepStats *stats,
 
 extern  MR_TrieNode MR_int_hash_lookup(MR_TrieNode table,
                         MR_Integer key);
+extern  MR_TrieNode MR_int64_hash_lookup(MR_TrieNode table,
+                        int64_t key);
+extern  MR_TrieNode MR_uint64_hash_lookup(MR_TrieNode table,
+                        uint64_t key);
 extern  MR_TrieNode MR_float_hash_lookup(MR_TrieNode table,
                         MR_Float key);
 extern  MR_TrieNode MR_string_hash_lookup(MR_TrieNode table,
diff --git a/runtime/mercury_tabling_macros.h b/runtime/mercury_tabling_macros.h
index c7399f6..007ad41 100644
--- a/runtime/mercury_tabling_macros.h
+++ b/runtime/mercury_tabling_macros.h
@@ -14,6 +14,8 @@
 
 #include "mercury_deep_copy.h"  // for MR_make_permanent
 
+#include <inttypes.h>
+
 #define MR_RAW_TABLE_ANY(table, type_info, value)                           \
     MR_table_type((table), (type_info), (value))
 
@@ -116,6 +118,18 @@
 #define MR_RAW_TABLE_UINT32_STATS(stats, table, value)                      \
     MR_word_hash_lookup_or_add_stats((stats), (table), (MR_Word)(value));
 
+#define MR_RAW_TABLE_INT64(table, value)                                    \
+    MR_int64_hash_lookup_or_add((table), (int64_t)(value));
+
+#define MR_RAW_TABLE_INT64_STATS(stats, table, value)                       \
+    MR_int64_hash_lookup_or_add_stats((stats), (table), (int64_t)(value));
+
+#define MR_RAW_TABLE_UINT64(table, value)                                   \
+    MR_uint64_hash_lookup_or_add((table), (uint64_t)(value));
+
+#define MR_RAW_TABLE_UINT64_STATS(stats, table, value)                      \
+    MR_uint64_hash_lookup_or_add_stats((stats), (table), (uint64_t)(value));
+
 #define MR_RAW_TABLE_CHAR(table, value)                                     \
     MR_int_hash_lookup_or_add((table), (value));
 
@@ -354,6 +368,33 @@
         }                                                                   \
     } while (0)
 
+#define MR_TABLE_INT64(stats, debug, back, t, t0, value)                    \
+    do {                                                                    \
+        if (stats != NULL) {                                                \
+            (t) = MR_RAW_TABLE_INT64_STATS((stats), (t0), (value));         \
+        } else {                                                            \
+            (t) = MR_RAW_TABLE_INT64((t0), (value));                        \
+        }                                                                   \
+        if (MR_tabledebug) {                                                \
+            printf("TABLE %p: int64 %" PRIx64 " => %p\n",                   \
+                (t0), (int64_t) (value), (t));                              \
+        }                                                                   \
+    } while (0)
+
+
+#define MR_TABLE_UINT64(stats, debug, back, t, t0, value)                   \
+    do {                                                                    \
+        if (stats != NULL) {                                                \
+            (t) = MR_RAW_TABLE_UINT64_STATS((stats), (t0), (value));        \
+        } else {                                                            \
+            (t) = MR_RAW_TABLE_UINT64((t0), (value));                       \
+        }                                                                   \
+        if (MR_tabledebug) {                                                \
+            printf("TABLE %p: uint64 %" PRIu64 " => %p\n",                  \
+                (t0), (uint64_t) (value), (t));                             \
+        }                                                                   \
+    } while (0)
+
 #define MR_TABLE_CHAR(stats, debug, back, t, t0, value)                     \
     do {                                                                    \
         if (stats != NULL) {                                                \
diff --git a/runtime/mercury_tabling_preds.h b/runtime/mercury_tabling_preds.h
index e3b8749..bc6432a 100644
--- a/runtime/mercury_tabling_preds.h
+++ b/runtime/mercury_tabling_preds.h
@@ -32,6 +32,10 @@
         MR_tbl_lookup_insert_int32(NULL, MR_FALSE, MR_FALSE, a, b, c)
 #define MR_table_lookup_insert_uint32(a, b, c)                              \
         MR_tbl_lookup_insert_uint32(NULL, MR_FALSE, MR_FALSE, a, b, c)
+#define MR_table_lookup_insert_int64(a, b, c)                               \
+        MR_tbl_lookup_insert_int64(NULL, MR_FALSE, MR_FALSE, a, b, c)
+#define MR_table_lookup_insert_uint64(a, b, c)                              \
+        MR_tbl_lookup_insert_uint64(NULL, MR_FALSE, MR_FALSE, a, b, c)
 #define MR_table_lookup_insert_start_int(a, b, c, d)                        \
         MR_tbl_lookup_insert_start_int(NULL, MR_FALSE, MR_FALSE, a, b, c, d)
 #define MR_table_lookup_insert_char(a, b, c)                                \
@@ -73,6 +77,10 @@
         MR_tbl_save_any_answer(MR_FALSE, a, b, c)
 #define MR_table_save_uint32_answer(a, b, c)                                \
         MR_tbl_save_any_answer(MR_FALSE, a, b, c)
+#define MR_table_save_int64_answer(a, b, c)                                 \
+        MR_tbl_save_any_answer(MR_FALSE, a, b, c)
+#define MR_table_save_uint64_answer(a, b, c)                                \
+        MR_tbl_save_any_answer(MR_FALSE, a, b, c)
 #define MR_table_save_char_answer(a, b, c)                                  \
         MR_tbl_save_char_answer(MR_FALSE, a, b, c)
 #define MR_table_save_string_answer(a, b, c)                                \
@@ -100,6 +108,10 @@
         MR_tbl_restore_any_answer(MR_FALSE, a, b, c)
 #define MR_table_restore_uint32_answer(a, b, c)                             \
         MR_tbl_restore_any_answer(MR_FALSE, a, b, c)
+#define MR_table_restore_int64_answer(a, b, c)                              \
+        MR_tbl_restore_any_answer(MR_FALSE, a, b, c)
+#define MR_table_restore_uint64_answer(a, b, c)                             \
+        MR_tbl_restore_any_answer(MR_FALSE, a, b, c)
 #define MR_table_restore_char_answer(a, b, c)                               \
         MR_tbl_restore_char_answer(MR_FALSE, a, b, c)
 #define MR_table_restore_string_answer(a, b, c)                             \
@@ -225,6 +237,16 @@
         MR_TABLE_UINT32(stats, debug, back, T, T0, (MR_Unsigned) V);        \
     } while (0)
 
+#define MR_tbl_lookup_insert_int64(stats, debug, back, T0, V, T)            \
+    do {                                                                    \
+        MR_TABLE_INT64(stats, debug, back, T, T0, (MR_Integer) V);          \
+    } while (0)
+
+#define MR_tbl_lookup_insert_uint64(stats, debug, back, T0, V, T)           \
+    do {                                                                    \
+        MR_TABLE_UINT64(stats, debug, back, T, T0, (MR_Unsigned) V);        \
+    } while (0)
+
 #define MR_tbl_lookup_insert_start_int(stats, debug, back, T0, S, V, T)     \
     do {                                                                    \
         MR_TABLE_START_INT(stats, debug, back, T, T0,                       \
@@ -340,6 +362,18 @@
             &MR_TYPE_CTOR_INFO_NAME(builtin, uint32, 0));                   \
     } while (0)
 
+#define MR_tbl_save_int64_answer(debug, AB, Offset, V)                      \
+    do {                                                                    \
+        MR_TABLE_SAVE_ANSWER(debug, AB, Offset, V,                          \
+            &MR_TYPE_CTOR_INFO_NAME(builtin, int64, 0));                    \
+    } while (0)
+
+#define MR_tbl_save_uint64_answer(debug, AB, Offset, V)                     \
+    do {                                                                    \
+        MR_TABLE_SAVE_ANSWER(debug, AB, Offset, V,                          \
+            &MR_TYPE_CTOR_INFO_NAME(builtin, uint64, 0));                   \
+    } while (0)
+
 #define MR_tbl_save_char_answer(debug, AB, Offset, V)                       \
     do {                                                                    \
         MR_TABLE_SAVE_ANSWER(debug, AB, Offset, V,                          \
@@ -411,6 +445,16 @@
         V = (uint32_t) MR_TABLE_GET_ANSWER(debug, AB, Offset);              \
     } while (0)
 
+#define MR_tbl_restore_int64_answer(debug, AB, Offset, V)                   \
+    do {                                                                    \
+        V = (int64_t) MR_TABLE_GET_ANSWER(debug, AB, Offset);               \
+    } while (0)
+
+#define MR_tbl_restore_uint64_answer(debug, AB, Offset, V)                  \
+    do {                                                                    \
+        V = (uint64_t) MR_TABLE_GET_ANSWER(debug, AB, Offset);              \
+    } while (0)
+
 #define MR_tbl_restore_char_answer(debug, AB, Offset, V)                    \
     do {                                                                    \
         V = (MR_Char) MR_TABLE_GET_ANSWER(debug, AB, Offset);               \
diff --git a/runtime/mercury_term_size.c b/runtime/mercury_term_size.c
index e2115e1..3253a95 100644
--- a/runtime/mercury_term_size.c
+++ b/runtime/mercury_term_size.c
@@ -321,6 +321,24 @@ try_again:
             }
 #endif
             return 0;
+        
+        case MR_TYPECTOR_REP_INT64:
+#ifdef MR_DEBUG_TERM_SIZES
+            if (MR_heapdebug && MR_lld_print_enabled) {
+                printf(
+                    "MR_term_size: int64 %p\n", (void *) term);
+            }
+#endif
+            return 0;
+
+        case MR_TYPECTOR_REP_UINT64:
+#ifdef MR_DEBUG_TERM_SIZES
+            if (MR_heapdebug && MR_lld_print_enabled) {
+                printf(
+                    "MR_term_size: uint64 %p\n", (void *) term);
+            }
+#endif
+            return 0;
 
         case MR_TYPECTOR_REP_CHAR:
 #ifdef MR_DEBUG_TERM_SIZES
diff --git a/runtime/mercury_type_info.h b/runtime/mercury_type_info.h
index bb95174..159df30 100644
--- a/runtime/mercury_type_info.h
+++ b/runtime/mercury_type_info.h
@@ -609,6 +609,8 @@ typedef enum {
     MR_DEFINE_BUILTIN_ENUM_CONST(MR_TYPECTOR_REP_UINT16),
     MR_DEFINE_BUILTIN_ENUM_CONST(MR_TYPECTOR_REP_INT32),
     MR_DEFINE_BUILTIN_ENUM_CONST(MR_TYPECTOR_REP_UINT32),
+    MR_DEFINE_BUILTIN_ENUM_CONST(MR_TYPECTOR_REP_INT64),
+    MR_DEFINE_BUILTIN_ENUM_CONST(MR_TYPECTOR_REP_UINT64),
     // MR_TYPECTOR_REP_UNKNOWN should remain the last alternative;
     // MR_TYPE_CTOR_STATS depends on this.
 
@@ -685,6 +687,8 @@ typedef MR_int_least16_t  MR_TypeCtorRepInt;
     "UINT16",                                                           \
     "INT32",                                                            \
     "UINT32",                                                           \
+    "INT64",                                                            \
+    "UINT64",                                                           \
     "UNKNOWN"
 
 extern  MR_ConstString  MR_ctor_rep_name[];
@@ -1445,6 +1449,12 @@ typedef void MR_CALL MR_CompareFunc_5(MR_Mercury_Type_Info,
   #define MR_UINT32_CTOR_ADDR                                             \
       (MR_Word *) &mercury__builtin__builtin__type_ctor_info_uint32_0
       // (MR_Word *) &MR_TYPE_CTOR_INFO_NAME(builtin, uint32, 0)
+  #define MR_INT64_CTOR_ADDR                                              \
+      (MR_Word *) &mercury__builtin__builtin__type_ctor_info_int64_0
+      // (MR_Word *) &MR_TYPE_CTOR_INFO_NAME(builtin, int64, 0)
+  #define MR_UINT64_CTOR_ADDR                                             \
+      (MR_Word *) &mercury__builtin__builtin__type_ctor_info_uint64_0
+      // (MR_Word *) &MR_TYPE_CTOR_INFO_NAME(builtin, uint64, 0)
   #define MR_FLOAT_CTOR_ADDR                                              \
       (MR_Word *) &mercury__builtin__builtin__type_ctor_info_float_0
       // (MR_Word *) &MR_TYPE_CTOR_INFO_NAME(builtin, float, 0)
diff --git a/runtime/mercury_unify_compare_body.h b/runtime/mercury_unify_compare_body.h
index 5e96b94..0e53429 100644
--- a/runtime/mercury_unify_compare_body.h
+++ b/runtime/mercury_unify_compare_body.h
@@ -680,6 +680,46 @@ start_label:
                 return_unify_answer(builtin, float, 0, fx == fy);
 #endif
             }
+        
+        case MR_TYPECTOR_REP_INT64:
+            {
+                int64_t   fx, fy;
+
+                fx = MR_word_to_int64(x);
+                fy = MR_word_to_int64(y);
+#ifdef  select_compare_code
+                if (fx == fy) {
+                    return_compare_answer(builtin, int64, 0, MR_COMPARE_EQUAL);
+                } else if (fx < fy) {
+                    return_compare_answer(builtin, int64, 0, MR_COMPARE_LESS);
+                } else {
+                    return_compare_answer(builtin, int64, 0,
+                        MR_COMPARE_GREATER);
+                }
+#else
+                return_unify_answer(builtin, int64, 0, fx == fy);
+#endif
+            }
+        
+        case MR_TYPECTOR_REP_UINT64:
+            {
+                uint64_t   fx, fy;
+
+                fx = MR_word_to_uint64(x);
+                fy = MR_word_to_uint64(y);
+#ifdef  select_compare_code
+                if (fx == fy) {
+                    return_compare_answer(builtin, uint64, 0, MR_COMPARE_EQUAL);
+                } else if (fx < fy) {
+                    return_compare_answer(builtin, uint64, 0, MR_COMPARE_LESS);
+                } else {
+                    return_compare_answer(builtin, uint64, 0,
+                        MR_COMPARE_GREATER);
+                }
+#else
+                return_unify_answer(builtin, uint64, 0, fx == fy);
+#endif
+            }
 
         case MR_TYPECTOR_REP_STRING:
             {


More information about the reviews mailing list