2 * x86 floating-point instructions.
4 * ----------------------------------------------------------------
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}
37 module Pos
= MakePos
(struct let name = "X86_as_float" end)
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
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
) } ->
59 | FL
, { funop_mem_double
= Some
(opcode
, extra3
) } ->
61 | FT
, { funop_mem_long_double
= Some
(opcode
, extra3
) } ->
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
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
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
119 FPStack i
, FPStack j
->
120 (match Int32.to_int i
, Int32.to_int j
with
122 opcode_float_st0_is_dst_flag
, op2
124 opcode_float_st0_is_src_flag
, op1
126 raise
(X86Exception
(pos, StringError
"as_print_binary_float_inst buf: illegal FP register combination")))
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
138 * Caml-master: "compile"