mirror of
https://github.com/ioacademy-jikim/debugging
synced 2025-06-11 09:56:29 +00:00
221 lines
7.5 KiB
C
221 lines
7.5 KiB
C
/* 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;
|
|
}
|