Got rid of previous stuff and just imported mcc.
[shack.git] / mcc-0.5.4rta03 / arch / x86 / as / x86_as_float.ml
blobf6533cc496cacb1b1879cc0568cfb6cf7b85f438
1 (*
2 * x86 floating-point instructions.
4 * ----------------------------------------------------------------
6 * @begin[license]
7 * Copyright (C) 2001 Jason Hickey, Caltech
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 * Author: Jason Hickey
24 * @email{jyh@cs.caltech.edu}
25 * @end[license]
27 open X86_inst_type
28 open X86_exn
29 open X86_pos
31 open X86_as_bfd.Buf
32 open X86_as_opcodes
33 open X86_as_util
34 open X86_as_opcode
35 open X86_as_modrm
37 module Pos = MakePos (struct let name = "X86_as_float" end)
38 open Pos
41 * Empty floating point instruction emits two opcode bytes.
43 let as_print_empty_float_inst buf opcodes =
44 let code16 = opcodes lsr 16 in
45 if code16 <> 0 then
46 bfd_print_int8 buf code16;
47 bfd_print_int8 buf (opcodes lsr 8);
48 bfd_print_int8 buf (opcodes land 0xff)
51 * This is a floating point memory operation,
52 * get the opcode and extra 3 bits.
54 let float_pre_op pos pre opcodes =
55 let pos = string_pos "float_pre_op" pos in
56 match pre, opcodes with
57 FS, { funop_mem_single = Some (opcode, extra3) } ->
58 opcode, extra3
59 | FL, { funop_mem_double = Some (opcode, extra3) } ->
60 opcode, extra3
61 | FT, { funop_mem_long_double = Some (opcode, extra3) } ->
62 opcode, extra3
63 | _ ->
64 raise (X86Exception (pos, StringError "as_print_unary_float_inst buf: illegal operand"))
67 * Print an instruction.
68 * this is effectively a unary instruction,
69 * but the dst argument may be used to modify the opcode.
71 let as_print_float_inst buf opcodes pos dst pre op =
72 let pos = string_pos "as_print_float_inst buf" pos in
73 match op, opcodes with
74 FPStack reg, { funop_stack = Some (opcode, extra3) } ->
75 let reg = Int32.to_int reg in
76 bfd_print_int8 buf (opcode lor dst);
77 as_print_modrm_reg_reg buf extra3 reg
79 | ImmediateLabel label, _ ->
80 let opcode, extra3 = float_pre_op pos pre opcodes in
81 bfd_print_int8 buf (opcode lor dst);
82 as_print_modrm_reg_label buf extra3 label false label
84 | MemReg reg, _ ->
85 let reg = number_of_register pos reg in
86 let opcode, extra3 = float_pre_op pos pre opcodes in
87 bfd_print_int8 buf (opcode lor dst);
88 as_print_modrm_reg_memreg buf extra3 reg
89 | MemRegOff (reg, off), _ ->
90 let reg = number_of_register pos reg in
91 let opcode, extra3 = float_pre_op pos pre opcodes in
92 bfd_print_int8 buf (opcode lor dst);
93 as_print_modrm_reg_memregoff buf extra3 reg off
94 | MemRegRegOffMul (r1, r2, off, mul), _ ->
95 let r1 = number_of_register pos r1 in
96 let r2 = number_of_register pos r2 in
97 let opcode, extra3 = float_pre_op pos pre opcodes in
98 bfd_print_int8 buf (opcode lor dst);
99 as_print_modrm_reg_memregregoffmul buf pos extra3 r1 r2 off mul
101 | _ ->
102 raise (X86Exception (pos, StringError "as_print_unary_float_inst buf: illegal operand"))
105 * For a unary instruction, the dst field is always 0.
107 let as_print_unary_float_inst buf opcodes pos pre op =
108 as_print_funop_prefix buf opcodes;
109 as_print_float_inst buf opcodes pos 0 pre op
112 * Print a binary instruction.
113 * dst operand must be stack register 0 or 1.
115 let as_print_binary_float_inst buf opcodes pos pre op1 op2 =
116 let pos = string_pos "as_print_binary_float_inst buf" pos in
117 let dst, op =
118 match op1, op2 with
119 FPStack i, FPStack j ->
120 (match Int32.to_int i, Int32.to_int j with
121 0, _ ->
122 opcode_float_st0_is_dst_flag, op2
123 | _, 0 ->
124 opcode_float_st0_is_src_flag, op1
125 | _ ->
126 raise (X86Exception (pos, StringError "as_print_binary_float_inst buf: illegal FP register combination")))
127 | _ ->
128 raise (X86Exception (pos, StringError "as_print_binary_float_inst buf: source, dest must both be FP registers"))
130 as_print_funop_prefix buf opcodes;
131 as_print_float_inst buf opcodes pos dst pre op
134 * @docoff
136 * -*-
137 * Local Variables:
138 * Caml-master: "compile"
139 * End:
140 * -*-