| /* 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; |
| } |