mirror of
https://github.com/ioacademy-jikim/debugging
synced 2025-06-11 09:56:29 +00:00
199 lines
6.7 KiB
C
199 lines
6.7 KiB
C
/* Test unsigned integer comparison ops
|
|
clr, clgr, clgfr, cl, clg, clgf, clfi, clgfi
|
|
|
|
missing: cly, clrl, clgrl, clgfrl
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdint.h>
|
|
#include <inttypes.h>
|
|
#include <limits.h>
|
|
#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;
|
|
}
|