__asm__ volatile (
"cvb %[result],%[input]\n\t"
: [result] "=d"(binary)
- : [input] "m"(decimal)
+ : [input] "R"(decimal)
);
return binary;
/*--- Helper for condition code. ---*/
/*------------------------------------------------------------*/
-/* Convert an IRRoundingMode value to s390_bfp_round_t */
#if defined(VGA_s390x)
+typedef long double Float128;
+union s390x_F64 { ULong i; Double f; };
+union s390x_F128 { struct { ULong hi, lo; } i; Float128 f; };
+
+/* Convert an IRRoundingMode value to s390_bfp_round_t */
static s390_bfp_round_t
decode_bfp_rounding_mode(UInt irrm)
{
}
vpanic("decode_bfp_rounding_mode");
}
-#endif
-
#define S390_CC_FOR_BINARY(opcode,cc_dep1,cc_dep2) \
({ \
/* Recover the original DEP2 value. See comment near s390_cc_thunk_put3 \
for rationale. */ \
cc_dep2 = cc_dep2 ^ cc_ndep; \
+ ULong tmp = 1; \
__asm__ volatile ( \
- "lghi 0,1\n\t" \
- "sr 0,%[op3]\n\t" /* borrow to cc */ \
+ "sr %[tmp],%[op3]\n\t" /* borrow to cc */ \
opcode " %[op1],%[op2]\n\t" /* then redo the op */\
- "ipm %[psw]\n\t" : [psw] "=d"(psw), [op1] "+&d"(cc_dep1) \
+ "ipm %[psw]\n\t" : [psw] "=d"(psw), [op1] "+&d"(cc_dep1), \
+ [tmp] "+&d"(tmp) \
: [op2] "d"(cc_dep2), [op3] "d"(cc_ndep) \
- : "0", "cc");\
+ : "cc");\
psw >> 28; /* cc */ \
})
/* Recover the original DEP2 value. See comment near s390_cc_thunk_put3 \
for rationale. */ \
cc_dep2 = cc_dep2 ^ cc_ndep; \
+ ULong tmp; \
__asm__ volatile ( \
- "lgfr 0,%[op3]\n\t" /* first load cc_ndep */ \
- "aghi 0,0\n\t" /* and convert it into a cc */ \
+ "lgfr %[tmp],%[op3]\n\t" /* first load cc_ndep */ \
+ "aghi %[tmp],0\n\t" /* and convert it into a cc */ \
opcode " %[op1],%[op2]\n\t" /* then redo the op */\
- "ipm %[psw]\n\t" : [psw] "=d"(psw), [op1] "+&d"(cc_dep1) \
+ "ipm %[psw]\n\t" : [psw] "=d"(psw), [op1] "+&d"(cc_dep1), \
+ [tmp] "=&d"(tmp) \
: [op2] "d"(cc_dep2), [op3] "d"(cc_ndep) \
- : "0", "cc");\
+ : "cc");\
psw >> 28; /* cc */ \
})
#define S390_CC_FOR_BFP_RESULT(opcode,cc_dep1) \
({ \
+ union s390x_F64 op = { .i = cc_dep1 }; \
+ Double tmp; \
__asm__ volatile ( \
- opcode " 0,%[op]\n\t" \
- "ipm %[psw]\n\t" : [psw] "=d"(psw) \
- : [op] "f"(cc_dep1) \
- : "cc", "f0");\
+ opcode " %[tmp],%[op]\n\t" \
+ "ipm %[psw]\n\t" : [psw] "=d"(psw), [tmp] "=f"(tmp) \
+ : [op] "f"(op.f) \
+ : "cc");\
psw >> 28; /* cc */ \
})
#define S390_CC_FOR_BFP128_RESULT(hi,lo) \
({ \
+ union s390x_F128 op = { .i = { hi, lo } }; \
+ Float128 tmp; \
__asm__ volatile ( \
- "ldr 4,%[high]\n\t" \
- "ldr 6,%[low]\n\t" \
- "ltxbr 0,4\n\t" \
- "ipm %[psw]\n\t" : [psw] "=d"(psw) \
- : [high] "f"(hi), [low] "f"(lo) \
- : "cc", "f0", "f2", "f4", "f6");\
+ "ltxbr %[tmp],%[op]\n\t" \
+ "ipm %[psw]\n\t" : [psw] "=d"(psw), [tmp] "=f"(tmp) \
+ : [op] "f"(op.f) \
+ : "cc");\
psw >> 28; /* cc */ \
})
#define S390_CC_FOR_BFP_CONVERT_AUX(opcode,cc_dep1,rounding_mode) \
({ \
+ union s390x_F64 op = { .i = cc_dep1 }; \
+ ULong tmp; \
__asm__ volatile ( \
- opcode " 0," #rounding_mode ",%[op]\n\t" \
- "ipm %[psw]\n\t" : [psw] "=d"(psw) \
- : [op] "f"(cc_dep1) \
- : "cc", "r0");\
+ opcode " %[tmp]," #rounding_mode ",%[op]\n\t" \
+ "ipm %[psw]\n\t" : [psw] "=d"(psw), [tmp] "=d"(tmp) \
+ : [op] "f"(op.f) \
+ : "cc");\
psw >> 28; /* cc */ \
})
#define S390_CC_FOR_BFP_UCONVERT_AUX(opcode,cc_dep1,rounding_mode) \
({ \
+ union s390x_F64 op = { .i = cc_dep1 }; \
+ ULong tmp; \
__asm__ volatile ( \
- opcode ",0,%[op]," #rounding_mode ",0\n\t" \
- "ipm %[psw]\n\t" : [psw] "=d"(psw) \
- : [op] "f"(cc_dep1) \
- : "cc", "r0");\
+ opcode ",%[tmp],%[op]," #rounding_mode ",0\n\t" \
+ "ipm %[psw]\n\t" : [psw] "=d"(psw), [tmp] "=d"(tmp) \
+ : [op] "f"(op.f) \
+ : "cc");\
psw >> 28; /* cc */ \
})
#define S390_CC_FOR_BFP128_CONVERT_AUX(opcode,hi,lo,rounding_mode) \
({ \
+ union s390x_F128 op = { .i = { hi, lo } }; \
+ ULong tmp; \
__asm__ volatile ( \
- "ldr 4,%[high]\n\t" \
- "ldr 6,%[low]\n\t" \
- opcode " 0," #rounding_mode ",4\n\t" \
- "ipm %[psw]\n\t" : [psw] "=d"(psw) \
- : [high] "f"(hi), [low] "f"(lo) \
- : "cc", "r0", "f4", "f6");\
+ opcode " %[tmp]," #rounding_mode ",%[op]\n\t" \
+ "ipm %[psw]\n\t" : [psw] "=d"(psw), [tmp] "=d"(tmp) \
+ : [op] "f"(op.f) \
+ : "cc");\
psw >> 28; /* cc */ \
})
#define S390_CC_FOR_BFP128_UCONVERT_AUX(opcode,hi,lo,rounding_mode) \
({ \
+ union s390x_F128 op = { .i = { hi, lo } }; \
+ ULong tmp; \
__asm__ volatile ( \
- "ldr 4,%[high]\n\t" \
- "ldr 6,%[low]\n\t" \
- opcode ",0,4," #rounding_mode ",0\n\t" \
- "ipm %[psw]\n\t" : [psw] "=d"(psw) \
- : [high] "f"(hi), [low] "f"(lo) \
- : "cc", "r0", "f4", "f6");\
+ opcode ",%[tmp],%[op]," #rounding_mode ",0\n\t" \
+ "ipm %[psw]\n\t" : [psw] "=d"(psw), [tmp] "=d"(tmp) \
+ : [op] "f"(op.f) \
+ : "cc");\
psw >> 28; /* cc */ \
})
#define S390_CC_FOR_BFP_TDC(opcode,cc_dep1,cc_dep2) \
({ \
+ union s390x_F64 val = { .i = cc_dep1 }; \
__asm__ volatile ( \
opcode " %[value],0(%[class])\n\t" \
"ipm %[psw]\n\t" : [psw] "=d"(psw) \
- : [value] "f"(cc_dep1), \
+ : [value] "f"(val.f), \
[class] "a"(cc_dep2) \
: "cc");\
psw >> 28; /* cc */ \
/* Recover the original DEP2 value. See comment near \
s390_cc_thunk_put1f128Z for rationale. */ \
cc_dep2 = cc_dep2 ^ cc_ndep; \
+ union s390x_F128 val = { .i = { cc_dep1, cc_dep2 } }; \
__asm__ volatile ( \
- "ldr 4,%[high]\n\t" \
- "ldr 6,%[low]\n\t" \
- "tcxb 4,0(%[class])\n\t" \
+ "tcxb %[value],0(%[class])\n\t" \
"ipm %[psw]\n\t" : [psw] "=d"(psw) \
- : [high] "f"(cc_dep1), [low] "f"(cc_dep2), \
- [class] "a"(cc_ndep) \
- : "cc", "f4", "f6");\
+ : [value] "f"(val.f), [class] "a"(cc_ndep) \
+ : "cc");\
psw >> 28; /* cc */ \
})
/* Convert an IRRoundingMode value to s390_dfp_round_t */
-#if defined(VGA_s390x)
static s390_dfp_round_t
decode_dfp_rounding_mode(UInt irrm)
{
}
vpanic("decode_dfp_rounding_mode");
}
-#endif
#define S390_CC_FOR_DFP_RESULT(cc_dep1) \
({ \
+ union s390x_F64 op = { .i = cc_dep1 }; \
+ Double tmp; \
__asm__ volatile ( \
- ".insn rre, 0xb3d60000,0,%[op]\n\t" /* LTDTR */ \
- "ipm %[psw]\n\t" : [psw] "=d"(psw) \
- : [op] "f"(cc_dep1) \
- : "cc", "f0"); \
+ ".insn rre, 0xb3d60000,%[tmp],%[op]\n\t" /* LTDTR */ \
+ "ipm %[psw]\n\t" : [psw] "=d"(psw), [tmp] "=f"(tmp) \
+ : [op] "f"(op.f) \
+ : "cc");\
psw >> 28; /* cc */ \
})
#define S390_CC_FOR_DFP128_RESULT(hi,lo) \
({ \
+ union s390x_F128 op = { .i = { hi, lo } }; \
+ Float128 tmp; \
__asm__ volatile ( \
- "ldr 4,%[high]\n\t" \
- "ldr 6,%[low]\n\t" \
- ".insn rre, 0xb3de0000,0,4\n\t" /* LTXTR */ \
- "ipm %[psw]\n\t" : [psw] "=d"(psw) \
- : [high] "f"(hi), [low] "f"(lo) \
- : "cc", "f0", "f2", "f4", "f6"); \
+ ".insn rre, 0xb3de0000,%[tmp],%[op]\n\t" /* LTXTR */ \
+ "ipm %[psw]\n\t" : [psw] "=d"(psw), [tmp] "=f"(tmp) \
+ : [op] "f"(op.f) \
+ : "cc"); \
psw >> 28; /* cc */ \
})
#define S390_CC_FOR_DFP_TD(opcode,cc_dep1,cc_dep2) \
({ \
+ union s390x_F64 val = { .i = cc_dep1 }; \
__asm__ volatile ( \
opcode ",%[value],0(%[class])\n\t" \
"ipm %[psw]\n\t" : [psw] "=d"(psw) \
- : [value] "f"(cc_dep1), \
+ : [value] "f"(val.f), \
[class] "a"(cc_dep2) \
: "cc"); \
psw >> 28; /* cc */ \
/* Recover the original DEP2 value. See comment near \
s390_cc_thunk_put1d128Z for rationale. */ \
cc_dep2 = cc_dep2 ^ cc_ndep; \
+ union s390x_F128 val = { .i = { cc_dep1, cc_dep2 } }; \
__asm__ volatile ( \
- "ldr 4,%[high]\n\t" \
- "ldr 6,%[low]\n\t" \
- opcode ",4,0(%[class])\n\t" \
+ opcode ",%[value],0(%[class])\n\t" \
"ipm %[psw]\n\t" : [psw] "=d"(psw) \
- : [high] "f"(cc_dep1), [low] "f"(cc_dep2), \
+ : [value] "f"(val.f), \
[class] "a"(cc_ndep) \
- : "cc", "f4", "f6"); \
+ : "cc"); \
psw >> 28; /* cc */ \
})
#define S390_CC_FOR_DFP_CONVERT_AUX(opcode,cc_dep1,rounding_mode) \
({ \
+ union s390x_F64 op = { .i = cc_dep1 }; \
+ Double tmp; \
__asm__ volatile ( \
- opcode ",0,%[op]," #rounding_mode ",0\n\t" \
- "ipm %[psw]\n\t" : [psw] "=d"(psw) \
- : [op] "f"(cc_dep1) \
- : "cc", "r0"); \
+ opcode ",%[tmp],%[op]," #rounding_mode ",0\n\t" \
+ "ipm %[psw]\n\t" : [psw] "=d"(psw), [tmp] "=f"(tmp) \
+ : [op] "f"(op.f) \
+ : "cc"); \
psw >> 28; /* cc */ \
})
#define S390_CC_FOR_DFP_UCONVERT_AUX(opcode,cc_dep1,rounding_mode) \
({ \
+ union s390x_F64 op = { .i = cc_dep1 }; \
+ Double tmp; \
__asm__ volatile ( \
- opcode ",0,%[op]," #rounding_mode ",0\n\t" \
- "ipm %[psw]\n\t" : [psw] "=d"(psw) \
- : [op] "f"(cc_dep1) \
- : "cc", "r0"); \
+ opcode ",%[tmp],%[op]," #rounding_mode ",0\n\t" \
+ "ipm %[psw]\n\t" : [psw] "=d"(psw), [tmp] "=f"(tmp) \
+ : [op] "f"(op.f) \
+ : "cc"); \
psw >> 28; /* cc */ \
})
#define S390_CC_FOR_DFP128_CONVERT_AUX(opcode,hi,lo,rounding_mode) \
({ \
+ union s390x_F128 op = { .i = { hi, lo } }; \
+ Double tmp; \
__asm__ volatile ( \
- "ldr 4,%[high]\n\t" \
- "ldr 6,%[low]\n\t" \
- opcode ",0,4," #rounding_mode ",0\n\t" \
- "ipm %[psw]\n\t" : [psw] "=d"(psw) \
- : [high] "f"(hi), [low] "f"(lo) \
- : "cc", "r0", "f4", "f6"); \
+ opcode ",%[tmp],%[op]," #rounding_mode ",0\n\t" \
+ "ipm %[psw]\n\t" : [psw] "=d"(psw), [tmp] "=f"(tmp) \
+ : [op] "f"(op.f) \
+ : "cc"); \
psw >> 28; /* cc */ \
})
cc; \
})
-#define S390_CC_FOR_DFP128_UCONVERT_AUX(opcode,hi,lo,rounding_mode) \
- ({ \
- __asm__ volatile ( \
- "ldr 4,%[high]\n\t" \
- "ldr 6,%[low]\n\t" \
- opcode ",0,4," #rounding_mode ",0\n\t" \
- "ipm %[psw]\n\t" : [psw] "=d"(psw) \
- : [high] "f"(hi), [low] "f"(lo) \
- : "cc", "r0", "f4", "f6"); \
- psw >> 28; /* cc */ \
+#define S390_CC_FOR_DFP128_UCONVERT_AUX(opcode,hi,lo,rounding_mode) \
+ ({ \
+ union s390x_F128 op = { .i = { hi, lo } }; \
+ Double tmp; \
+ __asm__ volatile ( \
+ opcode ",%[tmp],%[op]," #rounding_mode ",0\n\t" \
+ "ipm %[psw]\n\t" : [psw] "=d"(psw), [tmp] "=f"(tmp) \
+ : [op] "f"(op.f) \
+ : "cc"); \
+ psw >> 28; /* cc */ \
})
#define S390_CC_FOR_DFP128_UCONVERT(opcode,cc_dep1,cc_dep2,cc_ndep) \
} \
cc; \
})
+#endif /* VGA_s390x */
/* Return the value of the condition code from the supplied thunk parameters.
case S390_CC_OP_TEST_UNDER_MASK_8: {
UChar value = cc_dep1;
UChar mask = cc_dep2;
+ ULong pc;
__asm__ volatile (
- "bras %%r2,1f\n\t" /* %r2 = address of next insn */
+ "bras %[pc],1f\n\t" /* pc = address of next insn */
"tm %[value],0\n\t" /* this is skipped, then EXecuted */
- "1: ex %[mask],0(%%r2)\n\t" /* EXecute TM after modifying mask */
- "ipm %[psw]\n\t" : [psw] "=d"(psw)
- : [value] "m"(value), [mask] "a"(mask)
- : "r2", "cc");
+ "1: ex %[mask],0(%[pc])\n\t" /* EXecute TM after modifying mask */
+ "ipm %[psw]\n\t" : [psw] "=d"(psw), [pc] "=&a"(pc)
+ : [value] "Q"(value), [mask] "a"(mask)
+ : "cc");
return psw >> 28; /* cc */
}
"lhi 2,0x10\n\t"
"ex 2,%[insn]\n\t"
"ipm %[psw]\n\t" : [psw] "=d"(psw)
- : [value] "d"(value), [insn] "m"(insn)
+ : [value] "d"(value), [insn] "R"(insn)
: "r1", "r2", "cc");
return psw >> 28; /* cc */
}
case S390_CC_OP_PFPO_32: {
__asm__ volatile(
- "ler 4, %[cc_dep1]\n\t" /* 32 bit FR move */
- "lr 0, %[cc_dep2]\n\t" /* 32 bit GR move */
- ".short 0x010a\n\t" /* PFPO */
- "ipm %[psw]\n\t" : [psw] "=d"(psw)
- : [cc_dep1] "f"(cc_dep1),
+ "ldgr 4, %[cc_dep1]\n\t" /* Load FR from GR */
+ "lr 0, %[cc_dep2]\n\t" /* 32 bit GR move */
+ ".insn e,0x010a\n\t" /* PFPO */
+ "ipm %[psw]\n\t" : [psw] "=d"(psw)
+ : [cc_dep1] "d"(cc_dep1),
[cc_dep2] "d"(cc_dep2)
: "r0", "r1", "f4");
return psw >> 28; /* cc */
case S390_CC_OP_PFPO_64: {
__asm__ volatile(
- "ldr 4, %[cc_dep1]\n\t"
- "lr 0, %[cc_dep2]\n\t" /* 32 bit register move */
- ".short 0x010a\n\t" /* PFPO */
- "ipm %[psw]\n\t" : [psw] "=d"(psw)
- : [cc_dep1] "f"(cc_dep1),
+ "ldgr 4, %[cc_dep1]\n\t"
+ "lr 0, %[cc_dep2]\n\t" /* 32 bit register move */
+ ".insn e,0x010a\n\t" /* PFPO */
+ "ipm %[psw]\n\t" : [psw] "=d"(psw)
+ : [cc_dep1] "d"(cc_dep1),
[cc_dep2] "d"(cc_dep2)
: "r0", "r1", "f4");
return psw >> 28; /* cc */
case S390_CC_OP_PFPO_128: {
__asm__ volatile(
- "ldr 4,%[cc_dep1]\n\t"
- "ldr 6,%[cc_dep2]\n\t"
- "lr 0,%[cc_ndep]\n\t" /* 32 bit register move */
- ".short 0x010a\n\t" /* PFPO */
- "ipm %[psw]\n\t" : [psw] "=d"(psw)
- : [cc_dep1] "f"(cc_dep1),
- [cc_dep2] "f"(cc_dep2),
+ "ldgr 4,%[cc_dep1]\n\t"
+ "ldgr 6,%[cc_dep2]\n\t"
+ "lr 0,%[cc_ndep]\n\t" /* 32 bit register move */
+ ".insn e,0x010a\n\t" /* PFPO */
+ "ipm %[psw]\n\t" : [psw] "=d"(psw)
+ : [cc_dep1] "d"(cc_dep1),
+ [cc_dep2] "d"(cc_dep2),
[cc_ndep] "d"(cc_ndep)
: "r0", "r1", "f0", "f2", "f4", "f6");
return psw >> 28; /* cc */
[arg3] "r" (&guest_v[d->v4]),
[zero] "r" (0ULL),
- [insn] "m" (the_insn),
+ [insn] "R" (the_insn),
[read_only] "r" (d->read_only)
: "cc", "r10", "v16", "v17", "v18", "v19"