#include <assert.h>
#include "rounding.h"
-#define convert_to_int(opcode,src_type,dst_type,round,value,fmt) \
+// Convert to fixed
+#define CFEBR "0xb398"
+#define CFDBR "0xb399"
+#define CFXBR "0xb39a"
+#define CGEBR "0xb3a8"
+#define CGDBR "0xb3a8"
+#define CGXBR "0xb3aa"
+
+// Convert to logical
+#define CLFEBR "0xb39c"
+#define CLFDBR "0xb39d"
+#define CLFXBR "0xb39e"
+#define CLGEBR "0xb3ac"
+#define CLGDBR "0xb3ad"
+#define CLGXBR "0xb3ae"
+
+#define convert_to_int(mnm,opcode,src_type,dst_type,round,value,fmt) \
do { \
src_type src = value; \
dst_type dst; \
unsigned cc; \
\
- __asm__ volatile (opcode " %[dst]," #round ",%[src]\n\t" \
+ __asm__ volatile(".insn rrf," opcode "0000," "%[r1],%[r2],%[m3],0\n\t" \
"ipm %[cc]\n\t" \
"srl %[cc],28\n\t" \
- : [dst]"=d"(dst), [cc]"=d"(cc) \
- : [src]"f"(src) \
+ : [r1] "=d"(dst), [cc] "=d"(cc) \
+ : [r2] "f"(src), [m3] "i"(round) \
: "cc"); \
\
- printf("%s "fmt"\tcc = %u\n", opcode, src, cc); \
- \
- __asm__ volatile (opcode "a %[dst]," #round ",%[src],0\n\t" \
- "ipm %[cc]\n\t" \
- "srl %[cc],28\n\t" \
- : [dst]"=d"(dst), [cc]"=d"(cc) \
- : [src]"f"(src) \
- : "cc"); \
- \
- printf("%sa "fmt"\tcc = %u\n", opcode, src, cc); \
+ printf("%s "fmt"\tcc = %u\n", mnm, src, cc); \
} while (0)
-#define convert_to_logical(opcode,src_type,dst_type,round,value,fmt) \
+#define convert_to_logical(mnm,opcode,src_type,dst_type,round,value,fmt) \
do { \
src_type src = value; \
dst_type dst; \
unsigned cc; \
\
- __asm__ volatile (opcode " %[dst]," #round ",%[src], 0\n\t" \
- "ipm %[cc]\n\t" \
- "srl %[cc],28\n\t" \
- : [dst]"=d"(dst), [cc]"=d"(cc) \
- : [src]"f"(src) \
- : "cc"); \
+ __asm__ volatile(".insn rrf," opcode "0000," "%[r1],%[r2],%[m3],0\n\t" \
+ "ipm %[cc]\n\t" \
+ "srl %[cc],28\n\t" \
+ : [r1] "=d"(dst), [cc] "=d"(cc) \
+ : [r2] "f"(src), [m3] "i"(round) \
+ : "cc"); \
\
- printf("%s "fmt"\tcc = %u\n", opcode, src, cc); \
+ printf("%s "fmt"\tcc = %u\n", mnm, src, cc); \
} while (0)
/* Convenience macros */
#define cfebr(value,round) \
- convert_to_int("cfebr",float,int32_t,round,value,"%f")
+ convert_to_int("cfebr",CFEBR,float,int32_t,round,value,"%f")
#define cfdbr(value,round) \
- convert_to_int("cfdbr",double,int32_t,round,value,"%f")
+ convert_to_int("cfdbr",CFDBR,double,int32_t,round,value,"%f")
#define cfxbr(value,round) \
- convert_to_int("cfxbr",long double,int32_t,round,value,"%Lf")
+ convert_to_int("cfxbr",CFXBR,long double,int32_t,round,value,"%Lf")
#define cgebr(value,round) \
- convert_to_int("cgebr",float,int64_t,round,value,"%f")
+ convert_to_int("cgebr",CGEBR,float,int64_t,round,value,"%f")
#define cgdbr(value,round) \
- convert_to_int("cgdbr",double,int64_t,round,value,"%f")
+ convert_to_int("cgdbr",CGDBR,double,int64_t,round,value,"%f")
#define cgxbr(value,round) \
- convert_to_int("cgxbr",long double,int64_t,round,value,"%Lf")
+ convert_to_int("cgxbr",CGXBR,long double,int64_t,round,value,"%Lf")
#define clfebr(value,round) \
- convert_to_logical("clfebr",float,uint32_t,round,value,"%f")
+ convert_to_logical("clfebr",CLFEBR,float,uint32_t,round,value,"%f")
#define clfdbr(value,round) \
- convert_to_logical("clfdbr",double,uint32_t,round,value,"%f")
+ convert_to_logical("clfdbr",CLFDBR,double,uint32_t,round,value,"%f")
#define clfxbr(value,round) \
- convert_to_logical("clfxbr",long double,uint32_t,round,value,"%Lf")
+ convert_to_logical("clfxbr",CLFXBR,long double,uint32_t,round,value,"%Lf")
#define clgebr(value,round) \
- convert_to_logical("clgebr",float,uint64_t,round,value,"%f")
+ convert_to_logical("clgebr",CLGEBR,float,uint64_t,round,value,"%f")
#define clgdbr(value,round) \
- convert_to_logical("clgdbr",double,uint64_t,round,value,"%f")
+ convert_to_logical("clgdbr",CLGDBR,double,uint64_t,round,value,"%f")
#define clgxbr(value,round) \
- convert_to_logical("clgxbr",long double,uint64_t,round,value,"%Lf")
+ convert_to_logical("clgxbr",CLGXBR,long double,uint64_t,round,value,"%Lf")
#define convert_to_int_m3_tests(mode) \
printf("...setting M3 rounding mode to %s\n", m3_rtext(mode)); \
cgxbr(values[j], M3_BFP_ROUND_PER_FPC);
}
-/* Note: In order to get cc = 1 it is not sufficient for the operand value
- to be < 0. Additionally, the operand value after rounding must be 0. */
static void
convert_to_logical_fpc_tests(unsigned mode)
{