1663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include <stdint.h> 2663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#include <stdio.h> 3663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 4663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtypedef struct { 5663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng uint64_t high; 6663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng uint64_t low; 7663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} quad_word; 8663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 9663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid 10663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtest(quad_word op1_init, uint64_t op2_init, quad_word op3_init, 11663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng int expected_cc) 12663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 13663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng int cc = 1 - expected_cc; 14663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 15663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng quad_word op1 = op1_init; 16663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng uint64_t op2 = op2_init; 17663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng quad_word op3 = op3_init; 18663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 19663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng quad_word op1_before = op1; 20663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng uint64_t op2_before = op2; 21663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng quad_word op3_before = op3; 22663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 23663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("before op1 = (%#lx, %#lx)\n", op1.high, op1.low); 24663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("before op2 = %#lx\n", op2); 25663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("before op3 = (%#lx, %#lx)\n", op3.high, op3.low); 26663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 27663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ volatile ( 28663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lmg %%r0,%%r1,%1\n\t" 29663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lmg %%r2,%%r3,%3\n\t" 30663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "cds %%r0,%%r2,%2\n\t" // cds 1st,3rd,2nd 31663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "stmg %%r0,%%r1,%1\n" // store r0,r1 to op1 32663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "stmg %%r2,%%r3,%3\n" // store r2,r3 to op3 33663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "ipm %0\n\t" 34663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "srl %0,28\n\t" 35663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : "=d" (cc), "+QS" (op1), "+QS" (op2), "+QS" (op3) 36663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : 37663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : "r0", "r1", "r2", "r3", "cc"); 38663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 39663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("after op1 = (%#lx, %#lx)\n", op1.high, op1.low); 40663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("after op2 = %#lx\n", op2); 41663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("after op3 = (%#lx, %#lx)\n", op3.high, op3.low); 42663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("cc = %d\n", cc); 43663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 44663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // Check the condition code 45663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (cc != expected_cc) { 46663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("condition code is incorrect\n"); 47663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 48663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 49663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // op3 never changes 50663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (op3.low != op3_before.low || op3.high != op3_before.high) { 51663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("operand #3 modified\n"); 52663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 53663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 54663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (expected_cc == 0) { 55663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // 3rd operand stored at 2nd operand location 56663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 57663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // op1 did not change 58663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (op1.low != op1_before.low || op1.high != op1_before.high) { 59663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("operand #1 modified\n"); 60663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 61663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 62663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // lower 32 bits of op2 are the lower 32 bits of op3.low 63663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if ((op2 & 0xffffffff) != (op3.low & 0xffffffff)) { 64663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("operand #2 [32:63] incorrect\n"); 65663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 66663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // higher 32 bits of op2 are the lower 32 bits of op3.high 67663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if ((op2 >> 32) != (op3.high & 0xffffffff)) { 68663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("operand #2 [0:31] incorrect\n"); 69663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 70663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else { 71663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // 2nd operand stored at 1st operand location 72663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 73663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // op2 did not change 74663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (op2 != op2_before) { 75663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("operand #2 modified\n"); 76663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 77663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 78663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // bits [0:31] of op1 (both parts) are unchanged 79663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if ((op1.high >> 32) != (op1_before.high >> 32) || 80663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng (op1.low >> 32) != (op1_before.low >> 32)) { 81663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("operand #1 [0:31] modified\n"); 82663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 83663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 84663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if ((op1.low & 0xffffffff) != (op2 & 0xffffffff)) { 85663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("operand #1 low[32:63] incorrect\n"); 86663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 87663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if ((op1.high & 0xffffffff) != (op2 >> 32)) { 88663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("operand #1 high[32:63] not updated\n"); 89663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 90663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 91663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 92663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 93663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengint main () 94663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 95663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng quad_word op1, op3; 96663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng uint64_t op2; 97663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 98663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // (op1.high[32:63], op1.low[32:63]) == op2 99663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng op1.high = 0x0000000044556677ull; 100663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng op1.low = 0x111111118899aabbull; 101663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng op2 = 0x445566778899aabbull; 102663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 103663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng op3.high = op3.low = 0xdeadbeefdeadbabeull; 104663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng test(op1, op2, op3, 0); 105663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 106663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // (op1.high[32:63], op1.low[32:63]) != op2 107663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng op1.high = 0x1000000000000000ull; 108663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng op1.low = 0x0000000000000000ull; 109663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng op2 = 0x8000000000000001ull;; 110663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng op3.high = op3.low = 0xdeadbeefdeadbabeull; 111663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng test(op1, op2, op3, 1); 112663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 113663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return 0; 114663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 115