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