]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/valgrind/src/valgrind-3.6.0-svn/VEX/priv/host_s390_defs.h
update
[l4.git] / l4 / pkg / valgrind / src / valgrind-3.6.0-svn / VEX / priv / host_s390_defs.h
1 /* -*- mode: C; c-basic-offset: 3; -*- */
2
3 /*---------------------------------------------------------------*/
4 /*--- begin                                  host_s390_defs.h ---*/
5 /*---------------------------------------------------------------*/
6
7 /*
8    This file is part of Valgrind, a dynamic binary instrumentation
9    framework.
10
11    Copyright IBM Corp. 2010-2011
12
13    This program is free software; you can redistribute it and/or
14    modify it under the terms of the GNU General Public License as
15    published by the Free Software Foundation; either version 2 of the
16    License, or (at your option) any later version.
17
18    This program is distributed in the hope that it will be useful, but
19    WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21    General Public License for more details.
22
23    You should have received a copy of the GNU General Public License
24    along with this program; if not, write to the Free Software
25    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26    02110-1301, USA.
27
28    The GNU General Public License is contained in the file COPYING.
29 */
30
31 /* Contributed by Florian Krohm */
32
33 #ifndef __VEX_HOST_S390_DEFS_H
34 #define __VEX_HOST_S390_DEFS_H
35
36 #include "libvex_basictypes.h"            /* Bool */
37 #include "libvex.h"                       /* VexArchInfo */
38 #include "main_util.h"                    /* needed for host_generic_regs.h */
39 #include "host_generic_regs.h"            /* HReg */
40
41 /* --------- Registers --------- */
42 const HChar *s390_hreg_as_string(HReg);
43
44 void s390_hreg_get_allocable(Int *nregs, HReg **arr);
45
46 /* Dedicated registers */
47 HReg s390_hreg_guest_state_pointer(void);
48
49
50 /* Given the index of a function argument, return the number of the
51    general purpose register in which it is being passed. Arguments are
52    counted 0, 1, 2, ... and they are being passed in r2, r3, r4, ... */
53 static __inline__ unsigned
54 s390_gprno_from_arg_index(unsigned ix)
55 {
56    return ix + 2;
57 }
58
59 /* --------- Memory address expressions (amodes). --------- */
60
61 /* These are the address modes:
62    (1) b12:  base register + 12-bit unsigned offset   (e.g. RS)
63    (2) b20:  base register + 20-bit signed offset     (e.g. RSY)
64    (3) bx12: base register + index register + 12-bit unsigned offset (e.g. RX)
65    (4) bx20: base register + index register + 20-bit signed offset   (e.g. RXY)
66    fixs390: There is also pc-relative stuff.. e.g. LARL
67 */
68
69 typedef enum {
70    S390_AMODE_B12,
71    S390_AMODE_B20,
72    S390_AMODE_BX12,
73    S390_AMODE_BX20
74 } s390_amode_t;
75
76 typedef struct s390_amode {
77    s390_amode_t tag;
78    HReg b;
79    HReg x;       /* hregNumber(x) == 0  for S390_AMODE_B12/B20 kinds */
80    Int  d;       /* 12 bit unsigned or 20 bit signed */
81 } s390_amode;
82
83
84 s390_amode *s390_amode_b12(Int d, HReg b);
85 s390_amode *s390_amode_b20(Int d, HReg b);
86 s390_amode *s390_amode_bx12(Int d, HReg b, HReg x);
87 s390_amode *s390_amode_bx20(Int d, HReg b, HReg x);
88 s390_amode *s390_amode_for_guest_state(Int d);
89 Bool        s390_amode_is_sane(const s390_amode *);
90 void        s390_amode_get_reg_usage(HRegUsage *, const s390_amode *);
91 void        s390_amode_map_regs(HRegRemap *, s390_amode *);
92
93 const HChar *s390_amode_as_string(const s390_amode *);
94
95 struct s390_insn;
96 struct s390_amode;
97 /* ------------- 2nd (right) operand of binary operation ---------------- */
98
99 typedef enum {
100    S390_OPND_REG,
101    S390_OPND_IMMEDIATE,
102    S390_OPND_AMODE
103 } s390_opnd_t;
104
105
106 /* Naming convention for operand locations:
107    R    - GPR
108    I    - immediate value
109    M    - memory (any Amode may be used)
110 */
111
112 /* An operand that is either in a GPR or is addressable via a BX20 amode */
113 typedef struct {
114    s390_opnd_t tag;
115    union {
116       HReg        reg;
117       s390_amode *am;
118       ULong       imm;
119    } variant;
120 } s390_opnd_RMI;
121
122
123 /* The kind of instructions */
124 typedef enum {
125    S390_INSN_LOAD,   /* load register from memory */
126    S390_INSN_STORE,  /* store register to memory */
127    S390_INSN_MOVE,   /* from register to register */
128    S390_INSN_COND_MOVE, /* conditonal "move" to register */
129    S390_INSN_LOAD_IMMEDIATE,
130    S390_INSN_ALU,
131    S390_INSN_MUL,    /* n-bit operands; 2n-bit result */
132    S390_INSN_DIV,    /* 2n-bit dividend; n-bit divisor; n-bit quot/rem */
133    S390_INSN_DIVS,   /* n-bit dividend; n-bit divisor; n-bit quot/rem */
134    S390_INSN_CLZ,    /* count left-most zeroes */
135    S390_INSN_UNOP,
136    S390_INSN_TEST,   /* test operand and set cc */
137    S390_INSN_CC2BOOL,/* convert condition code to 0/1 */
138    S390_INSN_COMPARE,
139    S390_INSN_BRANCH, /* un/conditional goto */
140    S390_INSN_HELPER_CALL,
141    S390_INSN_CAS,    /* compare and swap */
142    S390_INSN_BFP_BINOP, /* Binary floating point 32-bit / 64-bit */
143    S390_INSN_BFP_UNOP,
144    S390_INSN_BFP_TRIOP,
145    S390_INSN_BFP_COMPARE,
146    S390_INSN_BFP128_BINOP, /* Binary floating point 128-bit */
147    S390_INSN_BFP128_UNOP,
148    S390_INSN_BFP128_COMPARE,
149    S390_INSN_BFP128_CONVERT_TO,
150    S390_INSN_BFP128_CONVERT_FROM,
151    S390_INSN_MFENCE
152 } s390_insn_tag;
153
154
155 /* The kind of ALU instructions */
156 typedef enum {
157    S390_ALU_ADD,
158    S390_ALU_SUB,
159    S390_ALU_MUL,   /* n-bit operands; result is lower n-bit of product */
160    S390_ALU_AND,
161    S390_ALU_OR,
162    S390_ALU_XOR,
163    S390_ALU_LSH,
164    S390_ALU_RSH,
165    S390_ALU_RSHA   /* arithmetic */
166 } s390_alu_t;
167
168
169 /* The kind of unary integer operations */
170 typedef enum {
171    S390_ZERO_EXTEND_8,
172    S390_ZERO_EXTEND_16,
173    S390_ZERO_EXTEND_32,
174    S390_SIGN_EXTEND_8,
175    S390_SIGN_EXTEND_16,
176    S390_SIGN_EXTEND_32,
177    S390_NEGATE
178 } s390_unop_t;
179
180 /* The kind of ternary BFP operations */
181 typedef enum {
182    S390_BFP_MADD,
183    S390_BFP_MSUB,
184 } s390_bfp_triop_t;
185
186 /* The kind of binary BFP operations */
187 typedef enum {
188    S390_BFP_ADD,
189    S390_BFP_SUB,
190    S390_BFP_MUL,
191    S390_BFP_DIV
192 } s390_bfp_binop_t;
193
194
195 /* The kind of unary BFP operations */
196 typedef enum {
197    S390_BFP_ABS,
198    S390_BFP_NABS,
199    S390_BFP_NEG,
200    S390_BFP_SQRT,
201    S390_BFP_I32_TO_F32,
202    S390_BFP_I32_TO_F64,
203    S390_BFP_I32_TO_F128,
204    S390_BFP_I64_TO_F32,
205    S390_BFP_I64_TO_F64,
206    S390_BFP_I64_TO_F128,
207    S390_BFP_F32_TO_I32,
208    S390_BFP_F32_TO_I64,
209    S390_BFP_F32_TO_F64,
210    S390_BFP_F32_TO_F128,
211    S390_BFP_F64_TO_I32,
212    S390_BFP_F64_TO_I64,
213    S390_BFP_F64_TO_F32,
214    S390_BFP_F64_TO_F128,
215    S390_BFP_F128_TO_I32,
216    S390_BFP_F128_TO_I64,
217    S390_BFP_F128_TO_F32,
218    S390_BFP_F128_TO_F64
219 } s390_bfp_unop_t;
220
221
222 /* Condition code. The encoding of the enumerators matches the value of
223    the mask field in the various branch opcodes. */
224 typedef enum {
225    S390_CC_NEVER=  0,
226    S390_CC_OVFL =  1,   /* overflow */
227    S390_CC_H    =  2,   /* A > B ; high */
228    S390_CC_NLE  =  3,   /* not low or equal */
229    S390_CC_L    =  4,   /* A < B ; low */
230    S390_CC_NHE  =  5,   /* not high or equal */
231    S390_CC_LH   =  6,   /* low or high */
232    S390_CC_NE   =  7,   /* A != B ; not zero */
233    S390_CC_E    =  8,   /* A == B ; zero */
234    S390_CC_NLH  =  9,   /* not low or high */
235    S390_CC_HE   = 10,   /* A >= B ; high or equal*/
236    S390_CC_NL   = 11,   /* not low */
237    S390_CC_LE   = 12,   /* A <= B ; low or equal */
238    S390_CC_NH   = 13,   /* not high */
239    S390_CC_NO   = 14,   /* not overflow */
240    S390_CC_ALWAYS = 15
241 } s390_cc_t;
242
243
244 /* Rounding mode as it is encoded in the m3/m4 fields of certain
245    instructions (e.g. CFEBR) */
246 typedef enum {
247 /* S390_ROUND_NEAREST_AWAY = 1, not supported */
248    S390_ROUND_NEAREST_EVEN = 4,
249    S390_ROUND_ZERO         = 5,
250    S390_ROUND_POSINF       = 6,
251    S390_ROUND_NEGINF       = 7
252 } s390_round_t;
253
254
255 /* Invert the condition code */
256 static __inline__ s390_cc_t
257 s390_cc_invert(s390_cc_t cond)
258 {
259    return S390_CC_ALWAYS - cond;
260 }
261
262
263 typedef struct s390_insn {
264    s390_insn_tag tag;
265    UChar size;            /* size of the result in bytes */
266    union {
267       struct {
268          HReg        dst;
269          s390_amode *src;
270       } load;
271       struct {
272          s390_amode *dst;
273          HReg        src;
274       } store;
275       struct {
276          HReg        dst;
277          HReg        src;
278       } move;
279       struct {
280          s390_cc_t     cond;
281          HReg          dst;
282          s390_opnd_RMI src;
283       } cond_move;
284       struct {
285          HReg        dst;
286          ULong       value;  /* not sign extended */
287       } load_immediate;
288       /* add, and, or, xor */
289       struct {
290          s390_alu_t    tag;
291          HReg          dst; /* op1 */
292          s390_opnd_RMI op2;
293       } alu;
294       struct {
295          Bool          signed_multiply;
296          HReg          dst_hi;  /*           r10 */
297          HReg          dst_lo;  /* also op1  r11 */
298          s390_opnd_RMI op2;
299       } mul;
300       struct {
301          Bool          signed_divide;
302          HReg          op1_hi;  /* also remainder   r10 */
303          HReg          op1_lo;  /* also quotient    r11 */
304          s390_opnd_RMI op2;
305       } div;
306       struct {
307          HReg          rem; /* remainder      r10 */
308          HReg          op1; /* also quotient  r11 */
309          s390_opnd_RMI op2;
310       } divs;
311       struct {
312          HReg          num_bits; /* number of leftmost '0' bits  r10 */
313          HReg          clobber;  /* unspecified                  r11 */
314          s390_opnd_RMI src;
315       } clz;
316       struct {
317          s390_unop_t   tag;
318          HReg          dst;
319          s390_opnd_RMI src;
320       } unop;
321       struct {
322          Bool          signed_comparison;
323          HReg          src1;
324          s390_opnd_RMI src2;
325       } compare;
326       struct {
327          HReg          dst;  /* condition code in s390 encoding */
328          HReg          op1;
329          HReg          op2;
330       } bfp_compare;
331       struct {
332          s390_opnd_RMI src;
333       } test;
334       /* Convert the condition code to a boolean value. */
335       struct {
336          s390_cc_t cond;
337          HReg      dst;
338       } cc2bool;
339       struct {
340          HReg        op1;
341          s390_amode *op2;
342          HReg        op3;
343          HReg        old_mem;
344       } cas;
345       struct {
346          IRJumpKind    kind;
347          s390_cc_t     cond;
348          s390_opnd_RMI dst;
349       } branch;
350       /* Pseudo-insn for representing a helper call.
351          TARGET is the absolute address of the helper function
352          NUM_ARGS says how many arguments are being passed.
353          All arguments have integer type and are being passed according to ABI,
354          i.e. in registers r2, r3, r4, r5, and r6, with argument #0 being
355          passed in r2 and so forth. */
356       struct {
357          s390_cc_t cond;
358          Addr64    target;
359          UInt      num_args;
360          HChar    *name;      /* callee's name (for debugging) */
361       } helper_call;
362       struct {
363          s390_bfp_triop_t tag;
364          s390_round_t     rounding_mode;
365          HReg             dst; /* first operand */
366          HReg             op2; /* second operand */
367          HReg             op3; /* third operand */
368       } bfp_triop;
369       struct {
370          s390_bfp_binop_t tag;
371          s390_round_t     rounding_mode;
372          HReg             dst; /* left operand */
373          HReg             op2; /* right operand */
374       } bfp_binop;
375       struct {
376          s390_bfp_unop_t tag;
377          s390_round_t    rounding_mode;
378          HReg            dst;  /* result */
379          HReg            op;   /* operand */
380       } bfp_unop;
381       struct {
382          s390_bfp_binop_t tag;
383          s390_round_t     rounding_mode;
384          HReg             dst_hi; /* left operand; high part */
385          HReg             dst_lo; /* left operand; low part */
386          HReg             op2_hi; /* right operand; high part */
387          HReg             op2_lo; /* right operand; low part */
388       } bfp128_binop;
389       /* This variant is also used by the BFP128_CONVERT_TO and
390          BFP128_CONVERT_FROM insns. */
391       struct {
392          s390_bfp_unop_t  tag;
393          s390_round_t     rounding_mode;
394          HReg             dst_hi; /* result; high part */
395          HReg             dst_lo; /* result; low part */
396          HReg             op_hi;  /* operand; high part */
397          HReg             op_lo;  /* operand; low part */
398       } bfp128_unop;
399       struct {
400          HReg             dst;    /* condition code in s390 encoding */
401          HReg             op1_hi; /* left operand; high part */
402          HReg             op1_lo; /* left operand; low part */
403          HReg             op2_hi; /* right operand; high part */
404          HReg             op2_lo; /* right operand; low part */
405       } bfp128_compare;
406    } variant;
407 } s390_insn;
408
409 s390_insn *s390_insn_load(UChar size, HReg dst, s390_amode *src);
410 s390_insn *s390_insn_store(UChar size, s390_amode *dst, HReg src);
411 s390_insn *s390_insn_move(UChar size, HReg dst, HReg src);
412 s390_insn *s390_insn_cond_move(UChar size, s390_cc_t cond, HReg dst,
413                                s390_opnd_RMI src);
414 s390_insn *s390_insn_load_immediate(UChar size, HReg dst, ULong val);
415 s390_insn *s390_insn_alu(UChar size, s390_alu_t, HReg dst,
416                          s390_opnd_RMI op2);
417 s390_insn *s390_insn_mul(UChar size, HReg dst_hi, HReg dst_lo,
418                          s390_opnd_RMI op2, Bool signed_multiply);
419 s390_insn *s390_insn_div(UChar size, HReg op1_hi, HReg op1_lo,
420                          s390_opnd_RMI op2, Bool signed_divide);
421 s390_insn *s390_insn_divs(UChar size, HReg rem, HReg op1, s390_opnd_RMI op2);
422 s390_insn *s390_insn_clz(UChar size, HReg num_bits, HReg clobber,
423                          s390_opnd_RMI op);
424 s390_insn *s390_insn_cas(UChar size, HReg op1, s390_amode *op2, HReg op3,
425                          HReg old);
426 s390_insn *s390_insn_unop(UChar size, s390_unop_t tag, HReg dst,
427                           s390_opnd_RMI opnd);
428 s390_insn *s390_insn_cc2bool(HReg dst, s390_cc_t src);
429 s390_insn *s390_insn_test(UChar size, s390_opnd_RMI src);
430 s390_insn *s390_insn_compare(UChar size, HReg dst, s390_opnd_RMI opnd,
431                              Bool signed_comparison);
432 s390_insn *s390_insn_branch(IRJumpKind jk, s390_cc_t cond, s390_opnd_RMI dst);
433 s390_insn *s390_insn_helper_call(s390_cc_t cond, Addr64 target, UInt num_args,
434                                  HChar *name);
435 s390_insn *s390_insn_bfp_triop(UChar size, s390_bfp_triop_t, HReg dst, HReg op2,
436                                HReg op3, s390_round_t);
437 s390_insn *s390_insn_bfp_binop(UChar size, s390_bfp_binop_t, HReg dst, HReg op2,
438                                s390_round_t);
439 s390_insn *s390_insn_bfp_unop(UChar size, s390_bfp_unop_t tag, HReg dst,
440                               HReg op, s390_round_t);
441 s390_insn *s390_insn_bfp_compare(UChar size, HReg dst, HReg op1, HReg op2);
442 s390_insn *s390_insn_bfp128_binop(UChar size, s390_bfp_binop_t, HReg dst_hi,
443                                   HReg dst_lo, HReg op2_hi, HReg op2_lo,
444                                   s390_round_t);
445 s390_insn *s390_insn_bfp128_unop(UChar size, s390_bfp_unop_t, HReg dst_hi,
446                                  HReg dst_lo, HReg op_hi, HReg op_lo,
447                                  s390_round_t);
448 s390_insn *s390_insn_bfp128_compare(UChar size, HReg dst, HReg op1_hi,
449                                     HReg op1_lo, HReg op2_hi, HReg op2_lo);
450 s390_insn *s390_insn_bfp128_convert_to(UChar size, s390_bfp_unop_t,
451                                        HReg dst_hi, HReg dst_lo, HReg op);
452 s390_insn *s390_insn_bfp128_convert_from(UChar size, s390_bfp_unop_t,
453                                          HReg dst, HReg op_hi, HReg op_lo,
454                                          s390_round_t);
455 s390_insn *s390_insn_mfence(void);
456 void       s390_insn_map_regs(HRegRemap *, s390_insn *);
457 Bool       s390_insn_is_reg_reg_move(const s390_insn *, HReg *, HReg *);
458 void       s390_insn_get_reg_usage(HRegUsage *u, const s390_insn *);
459 UInt       s390_insn_emit(UChar *buf, Int nbuf, const struct s390_insn *insn,
460                           void *dispatch);
461
462 const HChar *s390_insn_as_string(const s390_insn *);
463
464 /*--------------------------------------------------------*/
465 /* --- Interface exposed to VEX                       --- */
466 /*--------------------------------------------------------*/
467
468 void ppS390AMode(struct s390_amode *);
469 void ppS390Instr(struct s390_insn *, Bool mode64);
470 void ppHRegS390(HReg);
471
472 /* Some functions that insulate the register allocator from details
473    of the underlying instruction set. */
474 void  getRegUsage_S390Instr( HRegUsage *, struct s390_insn *, Bool );
475 void  mapRegs_S390Instr    ( HRegRemap *, struct s390_insn *, Bool );
476 Bool  isMove_S390Instr     ( struct s390_insn *, HReg *, HReg * );
477 Int   emit_S390Instr       ( UChar *, Int, struct s390_insn *, Bool, void * );
478 void  getAllocableRegs_S390( Int *, HReg **, Bool );
479 void  genSpill_S390        ( HInstr **, HInstr **, HReg , Int , Bool );
480 void  genReload_S390       ( HInstr **, HInstr **, HReg , Int , Bool );
481 struct s390_insn *directReload_S390 ( struct s390_insn *, HReg, Short );
482 HInstrArray *iselSB_S390   ( IRSB *, VexArch, VexArchInfo *, VexAbiInfo * );
483
484 /* KLUDGE: See detailled comment in host_s390_defs.c. */
485 extern const VexArchInfo *s390_archinfo_host;
486
487 /* Convenience macros to test installed facilities */
488 #define s390_host_has_ldisp \
489                       (s390_archinfo_host->hwcaps & (VEX_HWCAPS_S390X_LDISP))
490 #define s390_host_has_eimm \
491                       (s390_archinfo_host->hwcaps & (VEX_HWCAPS_S390X_EIMM))
492 #define s390_host_has_gie \
493                       (s390_archinfo_host->hwcaps & (VEX_HWCAPS_S390X_GIE))
494 #define s390_host_has_dfp \
495                       (s390_archinfo_host->hwcaps & (VEX_HWCAPS_S390X_DFP))
496 #define s390_host_has_fgx \
497                       (s390_archinfo_host->hwcaps & (VEX_HWCAPS_S390X_FGX))
498
499 #endif /* ndef __VEX_HOST_S390_DEFS_H */
500
501 /*---------------------------------------------------------------*/
502 /*--- end                                    host_s390_defs.h ---*/
503 /*---------------------------------------------------------------*/