1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
(***********************************************************************)
(* *)
(* Objective Caml *)
(* *)
(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
(* *)
(* Copyright 1996 Institut National de Recherche en Informatique et *)
(* Automatique. Distributed only by permission. *)
(* *)
(***********************************************************************)
(* $Id: arch_i386.ml,v 1.10 1996/05/24 15:17:02 xleroy Exp $ *)
(* Specific operations for the Intel 386 processor *)
type addressing_mode =
Ibased of string * int (* symbol + displ *)
| Iindexed of int (* reg + displ *)
| Iindexed2 of int (* reg + reg + displ *)
| Iscaled of int * int (* reg * scale + displ *)
| Iindexed2scaled of int * int (* reg + reg * scale + displ *)
type specific_operation =
Ilea of addressing_mode (* Lea gives scaled adds *)
| Istore_int of int * addressing_mode (* Store an integer constant *)
| Istore_symbol of string * addressing_mode (* Store a symbol *)
| Ioffset_loc of int * addressing_mode (* Add a constant to a location *)
| Ipush (* Push regs on stack *)
| Ipush_int of int (* Push an integer constant *)
| Ipush_symbol of string (* Push a symbol *)
| Ipush_load of addressing_mode (* Load a scalar and push *)
| Ipush_load_float of addressing_mode (* Load a float and push *)
| Isubfrev | Idivfrev (* Reversed float sub and div *)
| Ifloatarithmem of float_operation * addressing_mode (* float arith w/mem *)
and float_operation =
Ifloatadd | Ifloatsub | Ifloatsubrev | Ifloatmul | Ifloatdiv | Ifloatdivrev
(* Sizes, endianness *)
let big_endian = false
let size_addr = 4
let size_int = 4
let size_float = 8
(* Operations on addressing modes *)
let identity_addressing = Iindexed 0
let offset_addressing addr delta =
match addr with
Ibased(s, n) -> Ibased(s, n + delta)
| Iindexed n -> Iindexed(n + delta)
| Iindexed2 n -> Iindexed2(n + delta)
| Iscaled(scale, n) -> Iscaled(scale, n + delta)
| Iindexed2scaled(scale, n) -> Iindexed2scaled(scale, n + delta)
let num_args_addressing = function
Ibased(s, n) -> 0
| Iindexed n -> 1
| Iindexed2 n -> 2
| Iscaled(scale, n) -> 1
| Iindexed2scaled(scale, n) -> 2
(* Printing operations and addressing modes *)
open Format
let print_addressing printreg addr arg =
match addr with
Ibased(s, 0) ->
print_string "\""; print_string s; print_string "\""
| Ibased(s, n) ->
print_string "\""; print_string s; print_string "\" + "; print_int n
| Iindexed n ->
printreg arg.(0);
if n <> 0 then begin print_string " + "; print_int n end
| Iindexed2 n ->
printreg arg.(0); print_string " + "; printreg arg.(1);
if n <> 0 then begin print_string " + "; print_int n end
| Iscaled(scale, n) ->
printreg arg.(0); print_string " * "; print_int scale;
if n <> 0 then begin print_string " + "; print_int n end
| Iindexed2scaled(scale, n) ->
printreg arg.(0); print_string " + "; printreg arg.(1);
print_string " * "; print_int scale;
if n <> 0 then begin print_string " + "; print_int n end
let print_specific_operation printreg op arg =
match op with
Ilea addr -> print_addressing printreg addr arg
| Istore_int(n, addr) ->
print_string "["; print_addressing printreg addr arg;
print_string "] := "; print_int n
| Istore_symbol(lbl, addr) ->
print_string "["; print_addressing printreg addr arg;
print_string "] := \""; print_string lbl; print_string "\""
| Ioffset_loc(n, addr) ->
print_string "["; print_addressing printreg addr arg;
print_string "] +:= "; print_int n
| Ipush ->
print_string "push ";
for i = 0 to Array.length arg - 1 do
if i > 0 then print_string ", ";
printreg arg.(i)
done
| Ipush_int n ->
print_string "push "; print_int n
| Ipush_symbol s ->
print_string "push \""; print_string s; print_string "\""
| Ipush_load addr ->
print_string "push ["; print_addressing printreg addr arg;
print_string "]"
| Ipush_load_float addr ->
print_string "pushfloat ["; print_addressing printreg addr arg;
print_string "]"
| Isubfrev ->
printreg arg.(0); print_string " -f(rev) "; printreg arg.(1)
| Idivfrev ->
printreg arg.(0); print_string " /f(rev) "; printreg arg.(1)
| Ifloatarithmem(op, addr) ->
printreg arg.(0);
begin match op with
Ifloatadd -> print_string " +f "
| Ifloatsub -> print_string " -f "
| Ifloatsubrev -> print_string " -f(rev) "
| Ifloatmul -> print_string " *f "
| Ifloatdiv -> print_string " /f "
| Ifloatdivrev -> print_string " /f(rev) "
end;
print_string "[";
print_addressing printreg addr (Array.sub arg 1 (Array.length arg - 1));
print_string "]"
|