#include "libvex.h" // VexArch (needed by bb_to_IR.h)
#include "guest_generic_bb_to_IR.h" // DisResult
+
/* Convert one s390 insn to IR. See the type DisOneInstrFn in
bb_to_IR.h. */
-extern
DisResult disInstr_S390 ( IRSB* irbb,
Bool put_IP,
Bool (*resteerOkFn) ( void*, Addr64 ),
Bool host_bigendian );
/* Used by the optimiser to specialise calls to helpers. */
-extern
IRExpr* guest_s390x_spechelper ( HChar *function_name,
IRExpr **args,
IRStmt **precedingStmts,
/* Describes to the optimser which part of the guest state require
precise memory exceptions. This is logically part of the guest
state description. */
-extern
Bool guest_s390x_state_requires_precise_mem_exns ( Int, Int );
-extern
-VexGuestLayout s390xGuest_layout;
-
+extern VexGuestLayout s390xGuest_layout;
-UInt s390_decode_and_irgen(UChar *, UInt, DisResult *);
#define S390_GUEST_OFFSET(x) offsetof(VexGuestS390XState, x)
ULong s390x_dirtyhelper_STCKF(ULong *addr);
ULong s390x_dirtyhelper_STCKE(ULong *addr);
-/*------------------------------------------------------------*/
-/*--- IR generators for special opcodes. ---*/
-/*------------------------------------------------------------*/
-void s390_irgen_client_request(void);
-void s390_irgen_guest_NRADDR(void);
-void s390_irgen_call_noredir(void);
-void s390_irgen_internal_return(void);
-
-#include "libvex_basictypes.h"
-#include "libvex_ir.h"
/* The various ways to compute the condition code. */
-
enum {
S390_CC_OP_BITWISE = 0,
S390_CC_OP_SIGNED_COMPARE = 1,
*/
/*------------------------------------------------------------*/
-/*--- condition code helpers. ---*/
+/*--- Condition code helpers. ---*/
/*------------------------------------------------------------*/
UInt s390_calculate_cc(ULong cc_op, ULong cc_dep1, ULong cc_dep2,
ULong cc_ndep);
#include "host_s390_defs.h" /* S390_ROUND_xyzzy */
+/*------------------------------------------------------------*/
+/*--- Forward declarations ---*/
+/*------------------------------------------------------------*/
+static UInt s390_decode_and_irgen(UChar *, UInt, DisResult *);
+
+
/*------------------------------------------------------------*/
/*--- Globals ---*/
/*------------------------------------------------------------*/
/*--- Build IR for special instructions ---*/
/*------------------------------------------------------------*/
-void
+static void
s390_irgen_client_request(void)
{
if (0)
dis_res->whatNext = Dis_StopHere;
}
-void
+static void
s390_irgen_guest_NRADDR(void)
{
if (0)
put_gpr_dw0(3, IRExpr_Get(S390_GUEST_OFFSET(guest_NRADDR), Ity_I64));
}
-void
+static void
s390_irgen_call_noredir(void)
{
/* Continue after special op */
/* Function returns # bytes that were decoded or 0 in case of failure */
-UInt
+static UInt
s390_decode_and_irgen(UChar *bytes, UInt insn_length, DisResult *dres)
{
s390_decode_t status;
before they are emitted. */
const VexArchInfo *s390_archinfo_host;
+
+/*------------------------------------------------------------*/
+/*--- Forward declarations ---*/
+/*------------------------------------------------------------*/
+
+static Bool s390_insn_is_reg_reg_move(const s390_insn *, HReg *src, HReg *dst);
+static void s390_insn_map_regs(HRegRemap *, s390_insn *);
+static void s390_insn_get_reg_usage(HRegUsage *u, const s390_insn *);
+
+
/*------------------------------------------------------------*/
/*--- Registers ---*/
/*------------------------------------------------------------*/
/* Tell the register allocator which registers can be allocated. */
-void
+static void
s390_hreg_get_allocable(Int *nregs, HReg **arr)
{
UInt i;
/* Record the register use of an amode */
-void
+static void
s390_amode_get_reg_usage(HRegUsage *u, const s390_amode *am)
{
switch (am->tag) {
}
-void
+static void
s390_amode_map_regs(HRegRemap *m, s390_amode *am)
{
switch (am->tag) {
}
-
void
-ppS390AMode(struct s390_amode *am)
+ppS390AMode(s390_amode *am)
{
vex_printf("%s", s390_amode_as_string(am));
}
void
-ppS390Instr(struct s390_insn *insn, Bool mode64)
+ppS390Instr(s390_insn *insn, Bool mode64)
{
vex_printf("%s", s390_insn_as_string(insn));
}
/* Tell the register allocator how the given instruction uses the registers
it refers to. */
void
-getRegUsage_S390Instr(HRegUsage *u, struct s390_insn *insn, Bool mode64)
+getRegUsage_S390Instr(HRegUsage *u, s390_insn *insn, Bool mode64)
{
s390_insn_get_reg_usage(u, insn);
}
/* Map the registers of the given instruction */
void
-mapRegs_S390Instr(HRegRemap *m, struct s390_insn *insn, Bool mode64)
+mapRegs_S390Instr(HRegRemap *m, s390_insn *insn, Bool mode64)
{
s390_insn_map_regs(m, insn);
}
assign the source and destination to *src and *dst. If in doubt say No.
Used by the register allocator to do move coalescing. */
Bool
-isMove_S390Instr(struct s390_insn *insn, HReg *src, HReg *dst)
+isMove_S390Instr(s390_insn *insn, HReg *src, HReg *dst)
{
return s390_insn_is_reg_reg_move(insn, src, dst);
}
/* Tell the register allocator how the given insn uses the registers */
-void
+static void
s390_insn_get_reg_usage(HRegUsage *u, const s390_insn *insn)
{
initHRegUsage(u);
}
-void
+static void
s390_insn_map_regs(HRegRemap *m, s390_insn *insn)
{
switch (insn->tag) {
/* Return True, if INSN is a move between two registers of the same class.
In that case assign the source and destination registers to SRC and DST,
respectively. */
-Bool
+static Bool
s390_insn_is_reg_reg_move(const s390_insn *insn, HReg *src, HReg *dst)
{
if (insn->tag == S390_INSN_MOVE &&
/*--- Functions to emit a sequence of bytes ---*/
/*------------------------------------------------------------*/
-
static __inline__ UChar *
emit_2bytes(UChar *p, ULong val)
{
/*--- Functions to emit various instruction formats ---*/
/*------------------------------------------------------------*/
-
static UChar *
emit_RI(UChar *p, UInt op, UChar r1, UShort i2)
{
/*--- Functions to emit particular instructions ---*/
/*------------------------------------------------------------*/
-
static UChar *
s390_emit_AR(UChar *p, UChar r1, UChar r2)
{
Int
-emit_S390Instr(UChar *buf, Int nbuf, struct s390_insn *insn,
- Bool mode64,
+emit_S390Instr(UChar *buf, Int nbuf, s390_insn *insn, Bool mode64,
void *dispatch_unassisted, void *dispatch_assisted)
{
UChar *end;
/* --------- Registers --------- */
const HChar *s390_hreg_as_string(HReg);
-void s390_hreg_get_allocable(Int *nregs, HReg **arr);
-
/* Dedicated registers */
HReg s390_hreg_guest_state_pointer(void);
S390_AMODE_BX20
} s390_amode_t;
-typedef struct s390_amode {
+typedef struct {
s390_amode_t tag;
HReg b;
HReg x; /* hregNumber(x) == 0 for S390_AMODE_B12/B20 kinds */
s390_amode *s390_amode_bx20(Int d, HReg b, HReg x);
s390_amode *s390_amode_for_guest_state(Int d);
Bool s390_amode_is_sane(const s390_amode *);
-void s390_amode_get_reg_usage(HRegUsage *, const s390_amode *);
-void s390_amode_map_regs(HRegRemap *, s390_amode *);
const HChar *s390_amode_as_string(const s390_amode *);
-struct s390_insn;
-struct s390_amode;
/* ------------- 2nd (right) operand of binary operation ---------------- */
typedef enum {
}
-typedef struct s390_insn {
+typedef struct {
s390_insn_tag tag;
UChar size; /* size of the result in bytes */
union {
HReg dst, HReg op_hi, HReg op_lo,
s390_round_t);
s390_insn *s390_insn_mfence(void);
-void s390_insn_map_regs(HRegRemap *, s390_insn *);
-Bool s390_insn_is_reg_reg_move(const s390_insn *, HReg *, HReg *);
-void s390_insn_get_reg_usage(HRegUsage *u, const s390_insn *);
-UInt s390_insn_emit(UChar *buf, Int nbuf, const struct s390_insn *insn,
+UInt s390_insn_emit(UChar *buf, Int nbuf, const s390_insn *insn,
void *dispatch);
const HChar *s390_insn_as_string(const s390_insn *);
/* --- Interface exposed to VEX --- */
/*--------------------------------------------------------*/
-void ppS390AMode(struct s390_amode *);
-void ppS390Instr(struct s390_insn *, Bool mode64);
+void ppS390AMode(s390_amode *);
+void ppS390Instr(s390_insn *, Bool mode64);
void ppHRegS390(HReg);
/* Some functions that insulate the register allocator from details
of the underlying instruction set. */
-void getRegUsage_S390Instr( HRegUsage *, struct s390_insn *, Bool );
-void mapRegs_S390Instr ( HRegRemap *, struct s390_insn *, Bool );
-Bool isMove_S390Instr ( struct s390_insn *, HReg *, HReg * );
-Int emit_S390Instr ( UChar *, Int, struct s390_insn *, Bool,
+void getRegUsage_S390Instr( HRegUsage *, s390_insn *, Bool );
+void mapRegs_S390Instr ( HRegRemap *, s390_insn *, Bool );
+Bool isMove_S390Instr ( s390_insn *, HReg *, HReg * );
+Int emit_S390Instr ( UChar *, Int, s390_insn *, Bool,
void *, void * );
void getAllocableRegs_S390( Int *, HReg **, Bool );
void genSpill_S390 ( HInstr **, HInstr **, HReg , Int , Bool );
void genReload_S390 ( HInstr **, HInstr **, HReg , Int , Bool );
-struct s390_insn *directReload_S390 ( struct s390_insn *, HReg, Short );
+s390_insn *directReload_S390 ( s390_insn *, HReg, Short );
HInstrArray *iselSB_S390 ( IRSB *, VexArch, VexArchInfo *, VexAbiInfo * );
/* KLUDGE: See detailled comment in host_s390_defs.c. */