/* Test unsigned integer comparison ops clr, clgr, clgfr, cl, clg, clgf, clfi, clgfi missing: cly, clrl, clgrl, clgfrl */ #include #include #include #include #include "opcodes.h" #undef RIL_RU #define RIL_RU(op1,r1,op2,i2) \ ".short 0x" #op1 #r1 #op2 "\n\t" \ ".long " #i2 "\n\t" /* Perform a single unsigned comparison Both operands in register */ #define SCOMP_REG_REG(insn, v1, v2) \ ({ \ int cc; \ uint64_t op1 = v1; \ uint64_t op2 = v2; \ asm volatile( #insn " %1, %2\n\t" \ "ipm %0\n\t" \ "srl %0,28\n\t" \ : "=d" (cc) \ : "d" (op1), "d" (op2) \ : "cc"); \ printf("%.6s (%"PRIu64", %"PRIu64") --> cc = %d\n", \ #insn, op1, op2, cc); \ }) /* Perform a single unsigned comparison Left operand in register, right operand in memory */ #define SCOMP_REG_MEM(insn, v1, v2, op2_t) \ ({ \ int cc; \ uint64_t op1 = v1; \ op2_t op2 = v2; \ asm volatile( #insn " %1, %2\n\t" \ "ipm %0\n\t" \ "srl %0,28\n\t" \ : "=d" (cc) \ : "d" (op1), "Q" (op2) \ : "cc"); \ printf("%.6s (%"PRIu64", %"PRIu64") --> cc = %d\n", \ #insn, op1, (uint64_t)op2, cc); \ }) /* Perform a single unsigned comparison Left operand in register, right operand is an immediate constant */ #define SCOMP_REG_IMM(insn, v1, v2) \ ({ \ int cc; \ register uint64_t op1 asm("8") = v1; \ asm volatile( insn(8, v2) \ "ipm %0\n\t" \ "srl %0,28\n\t" \ : "=d" (cc) \ : "d" (op1) \ : "cc"); \ printf("%.6s (%"PRIu64", %"PRIu64") --> cc = %d\n", \ #insn, op1, (uint64_t)v2, cc); \ }) /* Run a sequence of unsigned comparisons for a given insn */ #define run_scomp_reg_reg(insn) \ ({ \ SCOMP_REG_REG(insn, 0, 0); \ SCOMP_REG_REG(insn, 0, 1); \ SCOMP_REG_REG(insn, 1, 0); \ SCOMP_REG_REG(insn, 2, 1); \ SCOMP_REG_REG(insn, 2, 2); \ SCOMP_REG_REG(insn, 2, 3); \ SCOMP_REG_REG(insn, 0, INT8_MAX); \ SCOMP_REG_REG(insn, INT8_MAX, 0); \ SCOMP_REG_REG(insn, INT8_MAX, INT8_MAX-1); \ SCOMP_REG_REG(insn, INT8_MAX, INT8_MAX); \ SCOMP_REG_REG(insn, 0, INT16_MAX); \ SCOMP_REG_REG(insn, INT16_MAX, 0); \ SCOMP_REG_REG(insn, INT16_MAX, INT16_MAX); \ SCOMP_REG_REG(insn, INT16_MAX, INT16_MAX-1); \ SCOMP_REG_REG(insn, 0, INT32_MAX); \ SCOMP_REG_REG(insn, INT32_MAX, 0); \ SCOMP_REG_REG(insn, INT32_MAX, INT32_MAX); \ SCOMP_REG_REG(insn, INT32_MAX, INT32_MAX-1); \ }) /* Run a sequence of signed comparisons for a given insn */ #define run_scomp_reg_mem(insn, op2_t) \ ({ \ SCOMP_REG_MEM(insn, 0, 0, op2_t); \ SCOMP_REG_MEM(insn, 0, 1, op2_t); \ SCOMP_REG_MEM(insn, 1, 0, op2_t); \ SCOMP_REG_MEM(insn, 2, 1, op2_t); \ SCOMP_REG_MEM(insn, 2, 2, op2_t); \ SCOMP_REG_MEM(insn, 2, 3, op2_t); \ SCOMP_REG_MEM(insn, 0, INT8_MAX, op2_t); \ SCOMP_REG_MEM(insn, INT8_MAX, 0, op2_t); \ SCOMP_REG_MEM(insn, INT8_MAX, INT8_MAX-1, op2_t); \ SCOMP_REG_MEM(insn, INT8_MAX, INT8_MAX, op2_t); \ SCOMP_REG_MEM(insn, 0, INT16_MAX, op2_t); \ SCOMP_REG_MEM(insn, INT16_MAX, 0, op2_t); \ SCOMP_REG_MEM(insn, INT16_MAX, INT16_MAX-1, op2_t); \ SCOMP_REG_MEM(insn, INT16_MAX, INT16_MAX, op2_t); \ SCOMP_REG_MEM(insn, 0, INT32_MAX, op2_t); \ SCOMP_REG_MEM(insn, INT32_MAX, 0, op2_t); \ SCOMP_REG_MEM(insn, INT32_MAX, INT32_MAX-1, op2_t); \ SCOMP_REG_MEM(insn, INT32_MAX, INT32_MAX, op2_t); \ }) /* Run a sequence of signed comparisons for a given insn */ #define run_scomp_reg_imm(insn) \ ({ \ SCOMP_REG_IMM(insn, 0, 0); \ SCOMP_REG_IMM(insn, 0, 1); \ SCOMP_REG_IMM(insn, 1, 0); \ SCOMP_REG_IMM(insn, 2, 1); \ SCOMP_REG_IMM(insn, 2, 2); \ SCOMP_REG_IMM(insn, 2, 3); \ SCOMP_REG_IMM(insn, INT8_MAX, 0); \ SCOMP_REG_IMM(insn, INT8_MAX, INT8_MAX-1); \ SCOMP_REG_IMM(insn, INT8_MAX, INT8_MAX); \ SCOMP_REG_IMM(insn, 0, INT16_MAX); \ SCOMP_REG_IMM(insn, INT16_MAX, 0); \ SCOMP_REG_IMM(insn, INT16_MAX, INT16_MAX); \ SCOMP_REG_IMM(insn, INT16_MAX, INT16_MAX-1); \ SCOMP_REG_IMM(insn, 0, INT32_MAX); \ SCOMP_REG_IMM(insn, INT32_MAX, 0); \ SCOMP_REG_IMM(insn, INT32_MAX, INT32_MAX); \ SCOMP_REG_IMM(insn, INT32_MAX, INT32_MAX-1); \ }) void signed_comparison_reg_reg(void) { run_scomp_reg_reg(clr); run_scomp_reg_reg(clgr); /* Special cases for clgr */ SCOMP_REG_REG(clgr, INT64_MIN, INT64_MIN); SCOMP_REG_REG(clgr, INT64_MIN, INT64_MAX); SCOMP_REG_REG(clgr, INT64_MAX, INT64_MIN); SCOMP_REG_REG(clgr, INT64_MAX, INT64_MAX); run_scomp_reg_reg(clgfr); /* Special cases for clgfr */ SCOMP_REG_REG(clgfr, INT64_MIN, INT32_MIN); SCOMP_REG_REG(clgfr, INT64_MIN, INT32_MAX); SCOMP_REG_REG(clgfr, INT64_MAX, INT32_MIN); SCOMP_REG_REG(clgfr, INT64_MAX, INT32_MAX); } void signed_comparison_reg_mem(void) { run_scomp_reg_mem(cl, int32_t); run_scomp_reg_mem(clg, int64_t); /* Special cases for clg */ SCOMP_REG_MEM(clg, INT64_MIN, INT64_MIN, int64_t); SCOMP_REG_MEM(clg, INT64_MIN, INT64_MAX, int64_t); SCOMP_REG_MEM(clg, INT64_MAX, INT64_MIN, int64_t); SCOMP_REG_MEM(clg, INT64_MAX, INT64_MAX, int64_t); run_scomp_reg_mem(clgf, int32_t); /* Special cases for clgf */ SCOMP_REG_MEM(clgf, INT64_MIN, INT32_MIN, int32_t); SCOMP_REG_MEM(clgf, INT64_MIN, INT32_MAX, int32_t); SCOMP_REG_MEM(clgf, INT64_MAX, INT32_MIN, int32_t); SCOMP_REG_MEM(clgf, INT64_MAX, INT32_MAX, int32_t); } void signed_comparison_reg_imm(void) { run_scomp_reg_imm(CLFI); run_scomp_reg_imm(CLGFI); /* Special cases for clgfi */ SCOMP_REG_IMM(CLGFI, INT64_MIN, INT32_MIN); SCOMP_REG_IMM(CLGFI, INT64_MIN, INT32_MAX); SCOMP_REG_IMM(CLGFI, INT64_MAX, INT32_MIN); SCOMP_REG_IMM(CLGFI, INT64_MAX, INT32_MAX); } int main(void) { signed_comparison_reg_reg(); signed_comparison_reg_mem(); signed_comparison_reg_imm(); return 0; }