1cc58cefa007df87ab22a79baa7ce4f2d1b627195florian#include <stdint.h> 2cc58cefa007df87ab22a79baa7ce4f2d1b627195florian#include <stdio.h> 3cc58cefa007df87ab22a79baa7ce4f2d1b627195florian 4cc58cefa007df87ab22a79baa7ce4f2d1b627195floriantypedef struct { 5cc58cefa007df87ab22a79baa7ce4f2d1b627195florian uint64_t high; 6cc58cefa007df87ab22a79baa7ce4f2d1b627195florian uint64_t low; 7cc58cefa007df87ab22a79baa7ce4f2d1b627195florian} quad_word; 8cc58cefa007df87ab22a79baa7ce4f2d1b627195florian 9cc58cefa007df87ab22a79baa7ce4f2d1b627195florianvoid 10cc58cefa007df87ab22a79baa7ce4f2d1b627195floriantest(quad_word op1_init, uint64_t op2_init, quad_word op3_init, 11cc58cefa007df87ab22a79baa7ce4f2d1b627195florian int expected_cc) 12cc58cefa007df87ab22a79baa7ce4f2d1b627195florian{ 13cc58cefa007df87ab22a79baa7ce4f2d1b627195florian int cc = 1 - expected_cc; 14cc58cefa007df87ab22a79baa7ce4f2d1b627195florian 15cc58cefa007df87ab22a79baa7ce4f2d1b627195florian quad_word op1 = op1_init; 16cc58cefa007df87ab22a79baa7ce4f2d1b627195florian uint64_t op2 = op2_init; 17cc58cefa007df87ab22a79baa7ce4f2d1b627195florian quad_word op3 = op3_init; 18cc58cefa007df87ab22a79baa7ce4f2d1b627195florian 19cc58cefa007df87ab22a79baa7ce4f2d1b627195florian quad_word op1_before = op1; 20cc58cefa007df87ab22a79baa7ce4f2d1b627195florian uint64_t op2_before = op2; 21cc58cefa007df87ab22a79baa7ce4f2d1b627195florian quad_word op3_before = op3; 22cc58cefa007df87ab22a79baa7ce4f2d1b627195florian 23cc58cefa007df87ab22a79baa7ce4f2d1b627195florian printf("before op1 = (%#lx, %#lx)\n", op1.high, op1.low); 24cc58cefa007df87ab22a79baa7ce4f2d1b627195florian printf("before op2 = %#lx\n", op2); 25cc58cefa007df87ab22a79baa7ce4f2d1b627195florian printf("before op3 = (%#lx, %#lx)\n", op3.high, op3.low); 26cc58cefa007df87ab22a79baa7ce4f2d1b627195florian 27cc58cefa007df87ab22a79baa7ce4f2d1b627195florian __asm__ volatile ( 28cc58cefa007df87ab22a79baa7ce4f2d1b627195florian "lmg %%r0,%%r1,%1\n\t" 29cc58cefa007df87ab22a79baa7ce4f2d1b627195florian "lmg %%r2,%%r3,%3\n\t" 30cc58cefa007df87ab22a79baa7ce4f2d1b627195florian "cds %%r0,%%r2,%2\n\t" // cds 1st,3rd,2nd 31cc58cefa007df87ab22a79baa7ce4f2d1b627195florian "stmg %%r0,%%r1,%1\n" // store r0,r1 to op1 32cc58cefa007df87ab22a79baa7ce4f2d1b627195florian "stmg %%r2,%%r3,%3\n" // store r2,r3 to op3 33cc58cefa007df87ab22a79baa7ce4f2d1b627195florian "ipm %0\n\t" 34cc58cefa007df87ab22a79baa7ce4f2d1b627195florian "srl %0,28\n\t" 35cc58cefa007df87ab22a79baa7ce4f2d1b627195florian : "=d" (cc), "+QS" (op1), "+QS" (op2), "+QS" (op3) 36cc58cefa007df87ab22a79baa7ce4f2d1b627195florian : 37cc58cefa007df87ab22a79baa7ce4f2d1b627195florian : "r0", "r1", "r2", "r3", "cc"); 38cc58cefa007df87ab22a79baa7ce4f2d1b627195florian 39cc58cefa007df87ab22a79baa7ce4f2d1b627195florian printf("after op1 = (%#lx, %#lx)\n", op1.high, op1.low); 40cc58cefa007df87ab22a79baa7ce4f2d1b627195florian printf("after op2 = %#lx\n", op2); 41cc58cefa007df87ab22a79baa7ce4f2d1b627195florian printf("after op3 = (%#lx, %#lx)\n", op3.high, op3.low); 42cc58cefa007df87ab22a79baa7ce4f2d1b627195florian printf("cc = %d\n", cc); 43cc58cefa007df87ab22a79baa7ce4f2d1b627195florian 44cc58cefa007df87ab22a79baa7ce4f2d1b627195florian // Check the condition code 45cc58cefa007df87ab22a79baa7ce4f2d1b627195florian if (cc != expected_cc) { 46cc58cefa007df87ab22a79baa7ce4f2d1b627195florian printf("condition code is incorrect\n"); 47cc58cefa007df87ab22a79baa7ce4f2d1b627195florian } 48cc58cefa007df87ab22a79baa7ce4f2d1b627195florian 49cc58cefa007df87ab22a79baa7ce4f2d1b627195florian // op3 never changes 50cc58cefa007df87ab22a79baa7ce4f2d1b627195florian if (op3.low != op3_before.low || op3.high != op3_before.high) { 51cc58cefa007df87ab22a79baa7ce4f2d1b627195florian printf("operand #3 modified\n"); 52cc58cefa007df87ab22a79baa7ce4f2d1b627195florian } 53cc58cefa007df87ab22a79baa7ce4f2d1b627195florian 54cc58cefa007df87ab22a79baa7ce4f2d1b627195florian if (expected_cc == 0) { 55cc58cefa007df87ab22a79baa7ce4f2d1b627195florian // 3rd operand stored at 2nd operand location 56cc58cefa007df87ab22a79baa7ce4f2d1b627195florian 57cc58cefa007df87ab22a79baa7ce4f2d1b627195florian // op1 did not change 58cc58cefa007df87ab22a79baa7ce4f2d1b627195florian if (op1.low != op1_before.low || op1.high != op1_before.high) { 59cc58cefa007df87ab22a79baa7ce4f2d1b627195florian printf("operand #1 modified\n"); 60cc58cefa007df87ab22a79baa7ce4f2d1b627195florian } 61cc58cefa007df87ab22a79baa7ce4f2d1b627195florian 62cc58cefa007df87ab22a79baa7ce4f2d1b627195florian // lower 32 bits of op2 are the lower 32 bits of op3.low 63cc58cefa007df87ab22a79baa7ce4f2d1b627195florian if ((op2 & 0xffffffff) != (op3.low & 0xffffffff)) { 64cc58cefa007df87ab22a79baa7ce4f2d1b627195florian printf("operand #2 [32:63] incorrect\n"); 65cc58cefa007df87ab22a79baa7ce4f2d1b627195florian } 66cc58cefa007df87ab22a79baa7ce4f2d1b627195florian // higher 32 bits of op2 are the lower 32 bits of op3.high 67cc58cefa007df87ab22a79baa7ce4f2d1b627195florian if ((op2 >> 32) != (op3.high & 0xffffffff)) { 68cc58cefa007df87ab22a79baa7ce4f2d1b627195florian printf("operand #2 [0:31] incorrect\n"); 69cc58cefa007df87ab22a79baa7ce4f2d1b627195florian } 70cc58cefa007df87ab22a79baa7ce4f2d1b627195florian } else { 71cc58cefa007df87ab22a79baa7ce4f2d1b627195florian // 2nd operand stored at 1st operand location 72cc58cefa007df87ab22a79baa7ce4f2d1b627195florian 73cc58cefa007df87ab22a79baa7ce4f2d1b627195florian // op2 did not change 74cc58cefa007df87ab22a79baa7ce4f2d1b627195florian if (op2 != op2_before) { 75cc58cefa007df87ab22a79baa7ce4f2d1b627195florian printf("operand #2 modified\n"); 76cc58cefa007df87ab22a79baa7ce4f2d1b627195florian } 77cc58cefa007df87ab22a79baa7ce4f2d1b627195florian 78cc58cefa007df87ab22a79baa7ce4f2d1b627195florian // bits [0:31] of op1 (both parts) are unchanged 79cc58cefa007df87ab22a79baa7ce4f2d1b627195florian if ((op1.high >> 32) != (op1_before.high >> 32) || 80cc58cefa007df87ab22a79baa7ce4f2d1b627195florian (op1.low >> 32) != (op1_before.low >> 32)) { 81cc58cefa007df87ab22a79baa7ce4f2d1b627195florian printf("operand #1 [0:31] modified\n"); 82cc58cefa007df87ab22a79baa7ce4f2d1b627195florian } 83cc58cefa007df87ab22a79baa7ce4f2d1b627195florian 84cc58cefa007df87ab22a79baa7ce4f2d1b627195florian if ((op1.low & 0xffffffff) != (op2 & 0xffffffff)) { 85cc58cefa007df87ab22a79baa7ce4f2d1b627195florian printf("operand #1 low[32:63] incorrect\n"); 86cc58cefa007df87ab22a79baa7ce4f2d1b627195florian } 87cc58cefa007df87ab22a79baa7ce4f2d1b627195florian if ((op1.high & 0xffffffff) != (op2 >> 32)) { 88cc58cefa007df87ab22a79baa7ce4f2d1b627195florian printf("operand #1 high[32:63] not updated\n"); 89cc58cefa007df87ab22a79baa7ce4f2d1b627195florian } 90cc58cefa007df87ab22a79baa7ce4f2d1b627195florian } 91cc58cefa007df87ab22a79baa7ce4f2d1b627195florian} 92cc58cefa007df87ab22a79baa7ce4f2d1b627195florian 93cc58cefa007df87ab22a79baa7ce4f2d1b627195florianint main () 94cc58cefa007df87ab22a79baa7ce4f2d1b627195florian{ 95cc58cefa007df87ab22a79baa7ce4f2d1b627195florian quad_word op1, op3; 96cc58cefa007df87ab22a79baa7ce4f2d1b627195florian uint64_t op2; 97cc58cefa007df87ab22a79baa7ce4f2d1b627195florian 98cc58cefa007df87ab22a79baa7ce4f2d1b627195florian // (op1.high[32:63], op1.low[32:63]) == op2 99cc58cefa007df87ab22a79baa7ce4f2d1b627195florian op1.high = 0x0000000044556677ull; 100cc58cefa007df87ab22a79baa7ce4f2d1b627195florian op1.low = 0x111111118899aabbull; 101cc58cefa007df87ab22a79baa7ce4f2d1b627195florian op2 = 0x445566778899aabbull; 102cc58cefa007df87ab22a79baa7ce4f2d1b627195florian 103cc58cefa007df87ab22a79baa7ce4f2d1b627195florian op3.high = op3.low = 0xdeadbeefdeadbabeull; 104cc58cefa007df87ab22a79baa7ce4f2d1b627195florian test(op1, op2, op3, 0); 105cc58cefa007df87ab22a79baa7ce4f2d1b627195florian 106cc58cefa007df87ab22a79baa7ce4f2d1b627195florian // (op1.high[32:63], op1.low[32:63]) != op2 107cc58cefa007df87ab22a79baa7ce4f2d1b627195florian op1.high = 0x1000000000000000ull; 108cc58cefa007df87ab22a79baa7ce4f2d1b627195florian op1.low = 0x0000000000000000ull; 109cc58cefa007df87ab22a79baa7ce4f2d1b627195florian op2 = 0x8000000000000001ull;; 110cc58cefa007df87ab22a79baa7ce4f2d1b627195florian op3.high = op3.low = 0xdeadbeefdeadbabeull; 111cc58cefa007df87ab22a79baa7ce4f2d1b627195florian test(op1, op2, op3, 1); 112cc58cefa007df87ab22a79baa7ce4f2d1b627195florian 113cc58cefa007df87ab22a79baa7ce4f2d1b627195florian return 0; 114cc58cefa007df87ab22a79baa7ce4f2d1b627195florian} 115