op_exception fgx stck stckf stcke stfle cksm mvcl clcl troo \
trto trot trtt tr tre cij cgij clij clgij crj cgrj clrj clgrj \
cs csg cds cdsg cu21 cu21_1 cu24 cu24_1 cu42 cu12 cu12_1 \
- ex_sig ex_clone cu14 cu14_1 cu41 fpconv ecag fpext fpext_warn
+ ex_sig ex_clone cu14 cu14_1 cu41 fpconv ecag fpext fpext_warn \
+ rounding-1
check_PROGRAMS = $(INSN_TESTS) \
allexec \
--- /dev/null
+#include <stdlib.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+/* This testcase is to illustrate that for convert to fixed the condition
+ code depends on the rounding mode. */
+
+const char *
+rtext(unsigned round)
+{
+ switch (round) {
+ case 0: return "[fpc]";
+ case 1: return "[->near/away]";
+ /* 2 is invalid */
+ case 3: return "[prep short]";
+ case 4: return "[->near/even]";
+ case 5: return "[->0]";
+ case 6: return "[->+inf]";
+ case 7: return "[->-inf]";
+ }
+ assert(0);
+}
+
+#define convert_to_int(opcode,src_type,dst_type,dst_fmt,round,value) \
+do { \
+ src_type src = value; \
+ dst_type dst; \
+ unsigned cc; \
+ \
+ __asm__ volatile (opcode " %[dst]," #round ",%[src]\n\t" \
+ "ipm %[cc]\n\t" \
+ "srl %[cc],28\n\t" \
+ : [dst] "=d"(dst), [cc] "=d"(cc) \
+ : [src] "f"(src) \
+ : "cc"); \
+ \
+ printf("%s %-20s %f\t-> %"dst_fmt"\tcc = %u\n", \
+ opcode, rtext(round), src, dst, cc); \
+} while (0)
+
+
+#define cfdbr(round,value) \
+ convert_to_int("cfdbr",double,int32_t,PRId32,round,value)
+
+int main(void)
+{
+ double dval;
+
+ dval = -2147483648.5; // a < MN
+
+ // f64 -> i32
+
+ cfdbr(4, dval); // round to nearest with ties to even
+ cfdbr(5, dval); // round to zero
+ cfdbr(6, dval); // round to +inf
+
+ /* The next invocation needs to give cc=3. It used to give cc=1 when
+ we were considering the to-be-converted value ONLY */
+ cfdbr(7, dval); // round to -inf
+
+ return 0;
+}