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} __attribute__((aligned(16))) quad_word; 8663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 9663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 10663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* CDSG needs quad-word alignment */ 11663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengquad_word _op1, _op2, _op3; 12663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 13663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengvoid 14663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengtest(quad_word op1_init, quad_word op2_init, quad_word op3_init, 15663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng int expected_cc) 16663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 17663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng quad_word op1_before, op2_before, op3_before; 18663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng int cc = 1 - expected_cc; 19663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 20663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _op1 = op1_init; 21663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _op2 = op2_init; 22663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng _op3 = op3_init; 23663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 24663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng op1_before = _op1; 25663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng op2_before = _op2; 26663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng op3_before = _op3; 27663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 28663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("before op1 = (%#lx, %#lx)\n", _op1.high, _op1.low); 29663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("before op2 = (%#lx, %#lx)\n", _op2.high, _op2.low); 30663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("before op3 = (%#lx, %#lx)\n", _op3.high, _op3.low); 31663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 32663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng __asm__ volatile ( 33663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lmg %%r0,%%r1,%1\n\t" 34663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "lmg %%r2,%%r3,%3\n\t" 35663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "cdsg %%r0,%%r2,%2\n\t" // cdsg 1st,3rd,2nd 36663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "stmg %%r0,%%r1,%1\n" // store r0,r1 to _op1 37663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "stmg %%r2,%%r3,%3\n" // store r2,r3 to _op3 38663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "ipm %0\n\t" 39663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng "srl %0,28\n\t" 40663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : "=d" (cc), "+QS" (_op1), "+QS" (_op2), "+QS" (_op3) 41663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : 42663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng : "r0", "r1", "r2", "r3", "cc"); 43663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 44663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("after op1 = (%#lx, %#lx)\n", _op1.high, _op1.low); 45663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("after op2 = (%#lx, %#lx)\n", _op2.high, _op2.low); 46663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("after op3 = (%#lx, %#lx)\n", _op3.high, _op3.low); 47663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("cc = %d\n", cc); 48663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 49663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (cc != expected_cc) { 50663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("condition code is incorrect\n"); 51663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 52663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 53663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // _op3 never changes 54663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (_op3.low != op3_before.low || _op3.high != op3_before.high) { 55663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("operand #3 modified\n"); 56663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 57663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 58663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (expected_cc == 0) { 59663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // 3rd operand stored at 2nd operand location 60663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 61663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // _op1 did not change 62663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (_op1.low != op1_before.low || _op1.high != op1_before.high) { 63663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("operand #1 modified\n"); 64663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 65663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (_op2.high != _op3.high || _op2.low != _op3.low) { 66663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("operand #2 incorrect\n"); 67663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 68663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } else { 69663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // 2nd operand stored at 1st operand location 70663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 71663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // _op2 did not change 72663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (_op2.low != op2_before.low || _op2.high != op2_before.high) { 73663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("operand #2 modified\n"); 74663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 75663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 76663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng if (_op1.high != _op2.high || _op1.low != _op2.low) { 77663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng printf("operand #1 incorrect\n"); 78663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 79663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng } 80663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 81663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 82663860b1408516d02ebfcb3a9999a134e6cfb223Ben Chengint main () 83663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng{ 84663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng quad_word op1, op2, op3; 85663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 86663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // op1 == op2 87663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng op1.high = 0x0011223344556677ull; 88663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng op1.low = 0x8899aabbccddeeffull; 89663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng op2 = op1; 90663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng op3.high = op3.low = 0xdeadbeefdeadbabeull; 91663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng test(op1, op2, op3, 0); 92663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 93663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // op1 != op2 (only MSB differs) 94663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng op1.high = 0x8000000000000000ull; 95663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng op1.low = 0x0000000000000000ull; 96663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng op2.high = 0; 97663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng op2.low = 1; 98663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng op3.high = op3.low = 0xdeadbeefdeadbabeull; 99663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng test(op1, op2, op3, 1); 100663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 101663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng // op1 != op2 (only LSB differs) 102663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng op1.high = 0x0000000000000000ull; 103663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng op1.low = 0x0000000000000001ull; 104663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng op2.high = 1; 105663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng op2.low = 0; 106663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng op3.high = op3.low = 0xdeadbeefdeadbabeull; 107663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng test(op1, op2, op3, 1); 108663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng 109663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng return 0; 110663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng} 111