/* Test signed integer comparison ops
cr, cgr, cgfr, c, cg, cgf, cfi, cgfi
missing: cy, crl, cgrl, cgfrl
*/
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <limits.h>
#include "opcodes.h"
#undef RIL_RI
#define RIL_RI(op1,r1,op2,i2) \
".short 0x" #op1 #r1 #op2 "\n\t" \
".long " #i2 "\n\t"
/* Perform a single signed comparison
Both operands in register */
#define SCOMP_REG_REG(insn, v1, v2) \
({ \
int cc; \
int64_t op1 = v1; \
int64_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 (%"PRId64", %"PRId64") --> cc = %d\n", \
#insn, op1, op2, cc); \
})
/* Perform a single signed comparison
Left operand in register, right operand in memory */
#define SCOMP_REG_MEM(insn, v1, v2, op2_t) \
({ \
int cc; \
int64_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 (%"PRId64", %"PRId64") --> cc = %d\n", \
#insn, op1, (int64_t)op2, cc); \
})
/* Perform a single signed comparison
Left operand in register, right operand is an immediate constant */
#define SCOMP_REG_IMM(insn, v1, v2) \
({ \
int cc; \
register int64_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 (%"PRId64", %"PRId64") --> cc = %d\n", \
#insn, op1, (int64_t)v2, cc); \
})
/* Run a sequence of signed 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, 0, -1); \
SCOMP_REG_REG(insn, 1, 0); \
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, 2, 1); \
SCOMP_REG_REG(insn, 2, 2); \
SCOMP_REG_REG(insn, 2, 3); \
SCOMP_REG_REG(insn, -2, 1); \
SCOMP_REG_REG(insn, 2, -1); \
SCOMP_REG_REG(insn, INT8_MIN, INT8_MIN); \
SCOMP_REG_REG(insn, INT8_MIN, INT8_MAX); \
SCOMP_REG_REG(insn, INT8_MAX, INT8_MIN); \
SCOMP_REG_REG(insn, INT8_MAX, INT8_MAX); \
SCOMP_REG_REG(insn, INT16_MIN, INT16_MIN); \
SCOMP_REG_REG(insn, INT16_MIN, INT16_MAX); \
SCOMP_REG_REG(insn, INT16_MAX, INT16_MIN); \
SCOMP_REG_REG(insn, INT16_MAX, INT16_MAX); \
SCOMP_REG_REG(insn, INT32_MIN, INT32_MIN); \
SCOMP_REG_REG(insn, INT32_MIN, INT32_MAX); \
SCOMP_REG_REG(insn, INT32_MAX, INT32_MIN); \
SCOMP_REG_REG(insn, INT32_MAX, INT32_MAX); \
})
/* 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, 0, -1, op2_t); \
SCOMP_REG_MEM(insn, 1, 0, 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, 2, 1, op2_t); \
SCOMP_REG_MEM(insn, 2, 2, op2_t); \
SCOMP_REG_MEM(insn, 2, 3, op2_t); \
SCOMP_REG_MEM(insn, -2, 1, op2_t); \
SCOMP_REG_MEM(insn, 2, -1, op2_t); \
SCOMP_REG_MEM(insn, INT8_MIN, INT8_MIN, op2_t); \
SCOMP_REG_MEM(insn, INT8_MIN, INT8_MAX, op2_t); \
SCOMP_REG_MEM(insn, INT8_MAX, INT8_MIN, op2_t); \
SCOMP_REG_MEM(insn, INT8_MAX, INT8_MAX, op2_t); \
SCOMP_REG_MEM(insn, INT16_MIN, INT16_MIN, op2_t); \
SCOMP_REG_MEM(insn, INT16_MIN, INT16_MAX, op2_t); \
SCOMP_REG_MEM(insn, INT16_MAX, INT16_MIN, op2_t); \
SCOMP_REG_MEM(insn, INT16_MAX, INT16_MAX, op2_t); \
SCOMP_REG_MEM(insn, INT32_MIN, INT32_MIN, op2_t); \
SCOMP_REG_MEM(insn, INT32_MIN, INT32_MAX, op2_t); \
SCOMP_REG_MEM(insn, INT32_MAX, INT32_MIN, 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, 0, -1); \
SCOMP_REG_IMM(insn, 1, 0); \
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, 2, 1); \
SCOMP_REG_IMM(insn, 2, 2); \
SCOMP_REG_IMM(insn, 2, 3); \
SCOMP_REG_IMM(insn, -2, 1); \
SCOMP_REG_IMM(insn, 2, -1); \
SCOMP_REG_IMM(insn, INT8_MIN, INT8_MIN); \
SCOMP_REG_IMM(insn, INT8_MIN, INT8_MAX); \
SCOMP_REG_IMM(insn, INT8_MAX, INT8_MIN); \
SCOMP_REG_IMM(insn, INT8_MAX, INT8_MAX); \
SCOMP_REG_IMM(insn, INT16_MIN, INT16_MIN); \
SCOMP_REG_IMM(insn, INT16_MIN, INT16_MAX); \
SCOMP_REG_IMM(insn, INT16_MAX, INT16_MIN); \
SCOMP_REG_IMM(insn, INT16_MAX, INT16_MAX); \
SCOMP_REG_IMM(insn, INT32_MIN, INT32_MIN); \
SCOMP_REG_IMM(insn, INT32_MIN, INT32_MAX); \
SCOMP_REG_IMM(insn, INT32_MAX, INT32_MIN); \
SCOMP_REG_IMM(insn, INT32_MAX, INT32_MAX); \
})
void
signed_comparison_reg_reg(void)
{
run_scomp_reg_reg(cr);
run_scomp_reg_reg(cgr);
/* Special cases for cgr */
SCOMP_REG_REG(cgr, INT64_MIN, INT64_MIN);
SCOMP_REG_REG(cgr, INT64_MIN, INT64_MAX);
SCOMP_REG_REG(cgr, INT64_MAX, INT64_MIN);
SCOMP_REG_REG(cgr, INT64_MAX, INT64_MAX);
run_scomp_reg_reg(cgfr);
/* Special cases for cgfr */
SCOMP_REG_REG(cgfr, INT64_MIN, INT32_MIN);
SCOMP_REG_REG(cgfr, INT64_MIN, INT32_MAX);
SCOMP_REG_REG(cgfr, INT64_MAX, INT32_MIN);
SCOMP_REG_REG(cgfr, INT64_MAX, INT32_MAX);
}
void
signed_comparison_reg_mem(void)
{
run_scomp_reg_mem(c, int32_t);
run_scomp_reg_mem(cg, int64_t);
/* Special cases for cg */
SCOMP_REG_MEM(cg, INT64_MIN, INT64_MIN, int64_t);
SCOMP_REG_MEM(cg, INT64_MIN, INT64_MAX, int64_t);
SCOMP_REG_MEM(cg, INT64_MAX, INT64_MIN, int64_t);
SCOMP_REG_MEM(cg, INT64_MAX, INT64_MAX, int64_t);
run_scomp_reg_mem(cgf, int32_t);
/* Special cases for cgf */
SCOMP_REG_MEM(cgf, INT64_MIN, INT32_MIN, int32_t);
SCOMP_REG_MEM(cgf, INT64_MIN, INT32_MAX, int32_t);
SCOMP_REG_MEM(cgf, INT64_MAX, INT32_MIN, int32_t);
SCOMP_REG_MEM(cgf, INT64_MAX, INT32_MAX, int32_t);
}
void
signed_comparison_reg_imm(void)
{
run_scomp_reg_imm(CFI);
run_scomp_reg_imm(CGFI);
/* Special cases for cgfi */
SCOMP_REG_IMM(CGFI, INT64_MIN, INT32_MIN);
SCOMP_REG_IMM(CGFI, INT64_MIN, INT32_MAX);
SCOMP_REG_IMM(CGFI, INT64_MAX, INT32_MIN);
SCOMP_REG_IMM(CGFI, INT64_MAX, INT32_MAX);
}
int main(void)
{
signed_comparison_reg_reg();
signed_comparison_reg_mem();
signed_comparison_reg_imm();
return 0;
}