guest_s390_helpers.c revision 49adf8664fa8e67c95397022d21ea1b547e2186b
12019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/* -*- mode: C; c-basic-offset: 3; -*- */ 22019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 32019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*---------------------------------------------------------------*/ 42019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*--- begin guest_s390_helpers.c ---*/ 52019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*---------------------------------------------------------------*/ 62019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 72019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/* 82019a976f07ff418dde2dfc7cc74667ef66d7764sewardj This file is part of Valgrind, a dynamic binary instrumentation 92019a976f07ff418dde2dfc7cc74667ef66d7764sewardj framework. 102019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 1189ae8477745fd2a15453557d729a50e627325ee2sewardj Copyright IBM Corp. 2010-2013 122019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 132019a976f07ff418dde2dfc7cc74667ef66d7764sewardj This program is free software; you can redistribute it and/or 142019a976f07ff418dde2dfc7cc74667ef66d7764sewardj modify it under the terms of the GNU General Public License as 152019a976f07ff418dde2dfc7cc74667ef66d7764sewardj published by the Free Software Foundation; either version 2 of the 162019a976f07ff418dde2dfc7cc74667ef66d7764sewardj License, or (at your option) any later version. 172019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 182019a976f07ff418dde2dfc7cc74667ef66d7764sewardj This program is distributed in the hope that it will be useful, but 192019a976f07ff418dde2dfc7cc74667ef66d7764sewardj WITHOUT ANY WARRANTY; without even the implied warranty of 202019a976f07ff418dde2dfc7cc74667ef66d7764sewardj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 212019a976f07ff418dde2dfc7cc74667ef66d7764sewardj General Public License for more details. 222019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 232019a976f07ff418dde2dfc7cc74667ef66d7764sewardj You should have received a copy of the GNU General Public License 242019a976f07ff418dde2dfc7cc74667ef66d7764sewardj along with this program; if not, write to the Free Software 252019a976f07ff418dde2dfc7cc74667ef66d7764sewardj Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 262019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 02110-1301, USA. 272019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 282019a976f07ff418dde2dfc7cc74667ef66d7764sewardj The GNU General Public License is contained in the file COPYING. 292019a976f07ff418dde2dfc7cc74667ef66d7764sewardj*/ 302019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 312019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/* Contributed by Florian Krohm */ 322019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 332019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#include "libvex_basictypes.h" 3433b024301d2311965cc68dc4cc900f3d0fdd8085florian#include "libvex_emnote.h" 352019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#include "libvex_guest_s390x.h" 362019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#include "libvex_ir.h" 372019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#include "libvex.h" 38933065d4f3548466da4666c5cfda7e5eaff93759florian#include "libvex_s390x_common.h" 392019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 402019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#include "main_util.h" 416c46befd9eb90c1b6e739926c1fa335cba75bf46philippe#include "main_globals.h" 422019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#include "guest_generic_bb_to_IR.h" 432019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#include "guest_s390_defs.h" 44b0b6710aa770763fd1fd5005075de8a8d5a269fbflorian#include "s390_defs.h" /* S390_BFP_ROUND_xyzzy */ 452019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 462019a976f07ff418dde2dfc7cc74667ef66d7764sewardjvoid 472019a976f07ff418dde2dfc7cc74667ef66d7764sewardjLibVEX_GuestS390X_initialise(VexGuestS390XState *state) 482019a976f07ff418dde2dfc7cc74667ef66d7764sewardj{ 492019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*------------------------------------------------------------*/ 502019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*--- Initialise ar registers ---*/ 512019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*------------------------------------------------------------*/ 522019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 532019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_a0 = 0; 542019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_a1 = 0; 552019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_a2 = 0; 562019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_a3 = 0; 572019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_a4 = 0; 582019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_a5 = 0; 592019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_a6 = 0; 602019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_a7 = 0; 612019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_a8 = 0; 622019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_a9 = 0; 632019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_a10 = 0; 642019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_a11 = 0; 652019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_a12 = 0; 662019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_a13 = 0; 672019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_a14 = 0; 682019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_a15 = 0; 692019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 702019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*------------------------------------------------------------*/ 712019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*--- Initialise fpr registers ---*/ 722019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*------------------------------------------------------------*/ 732019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 742019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_f0 = 0; 752019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_f1 = 0; 762019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_f2 = 0; 772019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_f3 = 0; 782019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_f4 = 0; 792019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_f5 = 0; 802019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_f6 = 0; 812019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_f7 = 0; 822019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_f8 = 0; 832019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_f9 = 0; 842019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_f10 = 0; 852019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_f11 = 0; 862019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_f12 = 0; 872019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_f13 = 0; 882019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_f14 = 0; 892019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_f15 = 0; 902019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 912019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*------------------------------------------------------------*/ 922019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*--- Initialise gpr registers ---*/ 932019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*------------------------------------------------------------*/ 942019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 952019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_r0 = 0; 962019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_r1 = 0; 972019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_r2 = 0; 982019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_r3 = 0; 992019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_r4 = 0; 1002019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_r5 = 0; 1012019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_r6 = 0; 1022019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_r7 = 0; 1032019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_r8 = 0; 1042019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_r9 = 0; 1052019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_r10 = 0; 1062019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_r11 = 0; 1072019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_r12 = 0; 1082019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_r13 = 0; 1092019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_r14 = 0; 1102019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_r15 = 0; 1112019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 1122019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*------------------------------------------------------------*/ 1132019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*--- Initialise S390 miscellaneous registers ---*/ 1142019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*------------------------------------------------------------*/ 1152019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 1162019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_counter = 0; 1172019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_fpc = 0; 1182019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_IA = 0; 1192019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 1202019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*------------------------------------------------------------*/ 1212019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*--- Initialise S390 pseudo registers ---*/ 1222019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*------------------------------------------------------------*/ 1232019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 1242019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_SYSNO = 0; 1252019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 1262019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*------------------------------------------------------------*/ 1272019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*--- Initialise generic pseudo registers ---*/ 1282019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*------------------------------------------------------------*/ 1292019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 1302019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_NRADDR = 0; 13105f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj state->guest_CMSTART = 0; 13205f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj state->guest_CMLEN = 0; 1332019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_IP_AT_SYSCALL = 0; 1346ef84bed9bb3af22060eb1759788034602bbcc88florian state->guest_EMNOTE = EmNote_NONE; 1358844a6329d275814456e3a2a5a7bffac75da0957florian state->host_EvC_COUNTER = 0; 1368844a6329d275814456e3a2a5a7bffac75da0957florian state->host_EvC_FAILADDR = 0; 1372019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 1382019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*------------------------------------------------------------*/ 1392019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*--- Initialise thunk ---*/ 1402019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*------------------------------------------------------------*/ 1412019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 1422019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_CC_OP = 0; 1432019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_CC_DEP1 = 0; 1442019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_CC_DEP2 = 0; 1452019a976f07ff418dde2dfc7cc74667ef66d7764sewardj state->guest_CC_NDEP = 0; 1465c328c00cfaad8b53006366e4db232543f8df5e1florian 1475c328c00cfaad8b53006366e4db232543f8df5e1florian __builtin_memset(state->padding, 0x0, sizeof(state->padding)); 1482019a976f07ff418dde2dfc7cc74667ef66d7764sewardj} 1492019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 1502019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 1512019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/* Figure out if any part of the guest state contained in minoff 1522019a976f07ff418dde2dfc7cc74667ef66d7764sewardj .. maxoff requires precise memory exceptions. If in doubt return 1536c46befd9eb90c1b6e739926c1fa335cba75bf46philippe True (but this generates significantly slower code). */ 1542019a976f07ff418dde2dfc7cc74667ef66d7764sewardjBool 1552019a976f07ff418dde2dfc7cc74667ef66d7764sewardjguest_s390x_state_requires_precise_mem_exns(Int minoff, Int maxoff) 1562019a976f07ff418dde2dfc7cc74667ef66d7764sewardj{ 157606878860623daa234c68fff81aade73059aaafbsewardj Int lr_min = S390X_GUEST_OFFSET(guest_LR); 1582019a976f07ff418dde2dfc7cc74667ef66d7764sewardj Int lr_max = lr_min + 8 - 1; 159606878860623daa234c68fff81aade73059aaafbsewardj Int sp_min = S390X_GUEST_OFFSET(guest_SP); 1602019a976f07ff418dde2dfc7cc74667ef66d7764sewardj Int sp_max = sp_min + 8 - 1; 161606878860623daa234c68fff81aade73059aaafbsewardj Int fp_min = S390X_GUEST_OFFSET(guest_FP); 1622019a976f07ff418dde2dfc7cc74667ef66d7764sewardj Int fp_max = fp_min + 8 - 1; 163e88b3c94d4e3bf0f40123ffe162dd60e50580366florian Int ia_min = S390X_GUEST_OFFSET(guest_IA); 1642019a976f07ff418dde2dfc7cc74667ef66d7764sewardj Int ia_max = ia_min + 8 - 1; 1652019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 1666c46befd9eb90c1b6e739926c1fa335cba75bf46philippe if (maxoff < sp_min || minoff > sp_max) { 1676c46befd9eb90c1b6e739926c1fa335cba75bf46philippe /* No overlap with SP */ 1686c46befd9eb90c1b6e739926c1fa335cba75bf46philippe if (vex_control.iropt_register_updates == VexRegUpdSpAtMemAccess) 1696c46befd9eb90c1b6e739926c1fa335cba75bf46philippe return False; // We only need to check stack pointer. 1702019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } else { 1712019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return True; 1722019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 1732019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 1746c46befd9eb90c1b6e739926c1fa335cba75bf46philippe if (maxoff < lr_min || minoff > lr_max) { 1756c46befd9eb90c1b6e739926c1fa335cba75bf46philippe /* No overlap with LR */ 1762019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } else { 1772019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return True; 1782019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 1792019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 1802019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (maxoff < fp_min || minoff > fp_max) { 1812019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* No overlap with FP */ 1822019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } else { 1832019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return True; 1842019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 1852019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 1862019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (maxoff < ia_min || minoff > ia_max) { 1872019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* No overlap with IA */ 1882019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } else { 1892019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return True; 1902019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 1912019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 1922019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return False; 1932019a976f07ff418dde2dfc7cc74667ef66d7764sewardj} 1942019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 1952019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 1962019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#define ALWAYSDEFD(field) \ 197e88b3c94d4e3bf0f40123ffe162dd60e50580366florian { S390X_GUEST_OFFSET(field), \ 1982019a976f07ff418dde2dfc7cc74667ef66d7764sewardj (sizeof ((VexGuestS390XState*)0)->field) } 1992019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 2002019a976f07ff418dde2dfc7cc74667ef66d7764sewardjVexGuestLayout s390xGuest_layout = { 2012019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 2022019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Total size of the guest state, in bytes. */ 2032019a976f07ff418dde2dfc7cc74667ef66d7764sewardj .total_sizeB = sizeof(VexGuestS390XState), 2042019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 2052019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Describe the stack pointer. */ 206606878860623daa234c68fff81aade73059aaafbsewardj .offset_SP = S390X_GUEST_OFFSET(guest_SP), 2072019a976f07ff418dde2dfc7cc74667ef66d7764sewardj .sizeof_SP = 8, 2082019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 2092019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Describe the frame pointer. */ 210606878860623daa234c68fff81aade73059aaafbsewardj .offset_FP = S390X_GUEST_OFFSET(guest_FP), 2112019a976f07ff418dde2dfc7cc74667ef66d7764sewardj .sizeof_FP = 8, 2122019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 2132019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Describe the instruction pointer. */ 214e88b3c94d4e3bf0f40123ffe162dd60e50580366florian .offset_IP = S390X_GUEST_OFFSET(guest_IA), 2152019a976f07ff418dde2dfc7cc74667ef66d7764sewardj .sizeof_IP = 8, 2162019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 2172019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Describe any sections to be regarded by Memcheck as 2182019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 'always-defined'. */ 2192019a976f07ff418dde2dfc7cc74667ef66d7764sewardj .n_alwaysDefd = 9, 2202019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 2212019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Flags thunk: OP and NDEP are always defined, whereas DEP1 2222019a976f07ff418dde2dfc7cc74667ef66d7764sewardj and DEP2 have to be tracked. See detailed comment in 2232019a976f07ff418dde2dfc7cc74667ef66d7764sewardj gdefs.h on meaning of thunk fields. */ 2242019a976f07ff418dde2dfc7cc74667ef66d7764sewardj .alwaysDefd = { 2252019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* 0 */ ALWAYSDEFD(guest_CC_OP), /* generic */ 2262019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* 1 */ ALWAYSDEFD(guest_CC_NDEP), /* generic */ 2276ef84bed9bb3af22060eb1759788034602bbcc88florian /* 2 */ ALWAYSDEFD(guest_EMNOTE), /* generic */ 22805f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj /* 3 */ ALWAYSDEFD(guest_CMSTART), /* generic */ 22905f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj /* 4 */ ALWAYSDEFD(guest_CMLEN), /* generic */ 2302019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* 5 */ ALWAYSDEFD(guest_IP_AT_SYSCALL), /* generic */ 2312019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* 6 */ ALWAYSDEFD(guest_IA), /* control reg */ 2322019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* 7 */ ALWAYSDEFD(guest_fpc), /* control reg */ 2332019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* 8 */ ALWAYSDEFD(guest_counter), /* internal usage register */ 2342019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 2352019a976f07ff418dde2dfc7cc74667ef66d7764sewardj}; 2362019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 2372019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*------------------------------------------------------------*/ 2382019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*--- Dirty helper for EXecute ---*/ 2392019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*------------------------------------------------------------*/ 2402019a976f07ff418dde2dfc7cc74667ef66d7764sewardjvoid 2412019a976f07ff418dde2dfc7cc74667ef66d7764sewardjs390x_dirtyhelper_EX(ULong torun) 2422019a976f07ff418dde2dfc7cc74667ef66d7764sewardj{ 2432019a976f07ff418dde2dfc7cc74667ef66d7764sewardj last_execute_target = torun; 2442019a976f07ff418dde2dfc7cc74667ef66d7764sewardj} 2452019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 2461e5fea63aab1f94925afd49d74560917b37fa505sewardj 2471e5fea63aab1f94925afd49d74560917b37fa505sewardj/*------------------------------------------------------------*/ 2481e5fea63aab1f94925afd49d74560917b37fa505sewardj/*--- Dirty helper for Clock instructions ---*/ 2491e5fea63aab1f94925afd49d74560917b37fa505sewardj/*------------------------------------------------------------*/ 2501e5fea63aab1f94925afd49d74560917b37fa505sewardj#if defined(VGA_s390x) 251ae88411aaa8e0b99032fb0bdb04eec21edc54d88florianULong 252ae88411aaa8e0b99032fb0bdb04eec21edc54d88florians390x_dirtyhelper_STCK(ULong *addr) 2531e5fea63aab1f94925afd49d74560917b37fa505sewardj{ 254ffbd84dd2205b38d45f3ce13d594787a7c62fd6cflorian UInt cc; 2551e5fea63aab1f94925afd49d74560917b37fa505sewardj 2561e5fea63aab1f94925afd49d74560917b37fa505sewardj asm volatile("stck %0\n" 2571e5fea63aab1f94925afd49d74560917b37fa505sewardj "ipm %1\n" 2581e5fea63aab1f94925afd49d74560917b37fa505sewardj "srl %1,28\n" 2591e5fea63aab1f94925afd49d74560917b37fa505sewardj : "+Q" (*addr), "=d" (cc) : : "cc"); 2601e5fea63aab1f94925afd49d74560917b37fa505sewardj return cc; 2611e5fea63aab1f94925afd49d74560917b37fa505sewardj} 2621e5fea63aab1f94925afd49d74560917b37fa505sewardj 263ae88411aaa8e0b99032fb0bdb04eec21edc54d88florianULong 264ae88411aaa8e0b99032fb0bdb04eec21edc54d88florians390x_dirtyhelper_STCKE(ULong *addr) 2651e5fea63aab1f94925afd49d74560917b37fa505sewardj{ 266ffbd84dd2205b38d45f3ce13d594787a7c62fd6cflorian UInt cc; 2671e5fea63aab1f94925afd49d74560917b37fa505sewardj 2681e5fea63aab1f94925afd49d74560917b37fa505sewardj asm volatile("stcke %0\n" 2691e5fea63aab1f94925afd49d74560917b37fa505sewardj "ipm %1\n" 2701e5fea63aab1f94925afd49d74560917b37fa505sewardj "srl %1,28\n" 2711e5fea63aab1f94925afd49d74560917b37fa505sewardj : "+Q" (*addr), "=d" (cc) : : "cc"); 2721e5fea63aab1f94925afd49d74560917b37fa505sewardj return cc; 2731e5fea63aab1f94925afd49d74560917b37fa505sewardj} 2741e5fea63aab1f94925afd49d74560917b37fa505sewardj 2751e5fea63aab1f94925afd49d74560917b37fa505sewardjULong s390x_dirtyhelper_STCKF(ULong *addr) 2761e5fea63aab1f94925afd49d74560917b37fa505sewardj{ 277ffbd84dd2205b38d45f3ce13d594787a7c62fd6cflorian UInt cc; 2781e5fea63aab1f94925afd49d74560917b37fa505sewardj 2791e5fea63aab1f94925afd49d74560917b37fa505sewardj asm volatile(".insn s,0xb27c0000,%0\n" 2801e5fea63aab1f94925afd49d74560917b37fa505sewardj "ipm %1\n" 2811e5fea63aab1f94925afd49d74560917b37fa505sewardj "srl %1,28\n" 2821e5fea63aab1f94925afd49d74560917b37fa505sewardj : "+Q" (*addr), "=d" (cc) : : "cc"); 2831e5fea63aab1f94925afd49d74560917b37fa505sewardj return cc; 2841e5fea63aab1f94925afd49d74560917b37fa505sewardj} 2851e5fea63aab1f94925afd49d74560917b37fa505sewardj#else 2861e5fea63aab1f94925afd49d74560917b37fa505sewardjULong s390x_dirtyhelper_STCK(ULong *addr) {return 3;} 2871e5fea63aab1f94925afd49d74560917b37fa505sewardjULong s390x_dirtyhelper_STCKF(ULong *addr) {return 3;} 2881e5fea63aab1f94925afd49d74560917b37fa505sewardjULong s390x_dirtyhelper_STCKE(ULong *addr) {return 3;} 2891e5fea63aab1f94925afd49d74560917b37fa505sewardj#endif /* VGA_s390x */ 2901e5fea63aab1f94925afd49d74560917b37fa505sewardj 2912019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*------------------------------------------------------------*/ 292933065d4f3548466da4666c5cfda7e5eaff93759florian/*--- Dirty helper for Store Facility instruction ---*/ 293933065d4f3548466da4666c5cfda7e5eaff93759florian/*------------------------------------------------------------*/ 294933065d4f3548466da4666c5cfda7e5eaff93759florian#if defined(VGA_s390x) 295b7def2222c08b119df85bc7231bf0e6806f3a1a6florianstatic void 296b7def2222c08b119df85bc7231bf0e6806f3a1a6florians390_set_facility_bit(ULong *addr, UInt bitno, UInt value) 297b7def2222c08b119df85bc7231bf0e6806f3a1a6florian{ 298b7def2222c08b119df85bc7231bf0e6806f3a1a6florian addr += bitno / 64; 299b7def2222c08b119df85bc7231bf0e6806f3a1a6florian bitno = bitno % 64; 300b7def2222c08b119df85bc7231bf0e6806f3a1a6florian 301b7def2222c08b119df85bc7231bf0e6806f3a1a6florian ULong mask = 1; 302b7def2222c08b119df85bc7231bf0e6806f3a1a6florian mask <<= (63 - bitno); 303b7def2222c08b119df85bc7231bf0e6806f3a1a6florian 304b7def2222c08b119df85bc7231bf0e6806f3a1a6florian if (value == 1) { 305b7def2222c08b119df85bc7231bf0e6806f3a1a6florian *addr |= mask; // set 306b7def2222c08b119df85bc7231bf0e6806f3a1a6florian } else { 307b7def2222c08b119df85bc7231bf0e6806f3a1a6florian *addr &= ~mask; // clear 308b7def2222c08b119df85bc7231bf0e6806f3a1a6florian } 309b7def2222c08b119df85bc7231bf0e6806f3a1a6florian} 310b7def2222c08b119df85bc7231bf0e6806f3a1a6florian 311933065d4f3548466da4666c5cfda7e5eaff93759florianULong 312ae88411aaa8e0b99032fb0bdb04eec21edc54d88florians390x_dirtyhelper_STFLE(VexGuestS390XState *guest_state, ULong *addr) 313933065d4f3548466da4666c5cfda7e5eaff93759florian{ 314933065d4f3548466da4666c5cfda7e5eaff93759florian ULong hoststfle[S390_NUM_FACILITY_DW], cc, num_dw, i; 315933065d4f3548466da4666c5cfda7e5eaff93759florian register ULong reg0 asm("0") = guest_state->guest_r0 & 0xF; /* r0[56:63] */ 316933065d4f3548466da4666c5cfda7e5eaff93759florian 317933065d4f3548466da4666c5cfda7e5eaff93759florian /* We cannot store more than S390_NUM_FACILITY_DW 318933065d4f3548466da4666c5cfda7e5eaff93759florian (and it makes not much sense to do so anyhow) */ 319933065d4f3548466da4666c5cfda7e5eaff93759florian if (reg0 > S390_NUM_FACILITY_DW - 1) 320933065d4f3548466da4666c5cfda7e5eaff93759florian reg0 = S390_NUM_FACILITY_DW - 1; 321933065d4f3548466da4666c5cfda7e5eaff93759florian 322933065d4f3548466da4666c5cfda7e5eaff93759florian num_dw = reg0 + 1; /* number of double words written */ 323933065d4f3548466da4666c5cfda7e5eaff93759florian 324933065d4f3548466da4666c5cfda7e5eaff93759florian asm volatile(" .insn s,0xb2b00000,%0\n" /* stfle */ 325933065d4f3548466da4666c5cfda7e5eaff93759florian "ipm %2\n" 326933065d4f3548466da4666c5cfda7e5eaff93759florian "srl %2,28\n" 327933065d4f3548466da4666c5cfda7e5eaff93759florian : "=m" (hoststfle), "+d"(reg0), "=d"(cc) : : "cc", "memory"); 328933065d4f3548466da4666c5cfda7e5eaff93759florian 329933065d4f3548466da4666c5cfda7e5eaff93759florian /* Update guest register 0 with what STFLE set r0 to */ 330933065d4f3548466da4666c5cfda7e5eaff93759florian guest_state->guest_r0 = reg0; 331933065d4f3548466da4666c5cfda7e5eaff93759florian 332b7def2222c08b119df85bc7231bf0e6806f3a1a6florian /* Set default: VM facilities = host facilities */ 333933065d4f3548466da4666c5cfda7e5eaff93759florian for (i = 0; i < num_dw; ++i) 334ae88411aaa8e0b99032fb0bdb04eec21edc54d88florian addr[i] = hoststfle[i]; 335933065d4f3548466da4666c5cfda7e5eaff93759florian 336b7def2222c08b119df85bc7231bf0e6806f3a1a6florian /* Now adjust the VM facilities according to what the VM supports */ 337b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_LDISP, 1); 338b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_EIMM, 1); 339b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_ETF2, 1); 340b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_ETF3, 1); 341b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_GIE, 1); 342b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_EXEXT, 1); 343b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_HIGHW, 1); 344b7def2222c08b119df85bc7231bf0e6806f3a1a6florian 345b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_HFPMAS, 0); 346b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_HFPUNX, 0); 347b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_XCPUT, 0); 348b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_MSA, 0); 349b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_PENH, 0); 350b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_DFP, 0); 351b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_PFPO, 0); 352b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_DFPZC, 0); 353b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_MISC, 0); 354b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_CTREXE, 0); 355b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_TREXE, 0); 356b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_MSA4, 0); 357b7def2222c08b119df85bc7231bf0e6806f3a1a6florian 358933065d4f3548466da4666c5cfda7e5eaff93759florian return cc; 359933065d4f3548466da4666c5cfda7e5eaff93759florian} 360933065d4f3548466da4666c5cfda7e5eaff93759florian 361933065d4f3548466da4666c5cfda7e5eaff93759florian#else 362933065d4f3548466da4666c5cfda7e5eaff93759florian 363933065d4f3548466da4666c5cfda7e5eaff93759florianULong 364ae88411aaa8e0b99032fb0bdb04eec21edc54d88florians390x_dirtyhelper_STFLE(VexGuestS390XState *guest_state, ULong *addr) 365933065d4f3548466da4666c5cfda7e5eaff93759florian{ 366933065d4f3548466da4666c5cfda7e5eaff93759florian return 3; 367933065d4f3548466da4666c5cfda7e5eaff93759florian} 368933065d4f3548466da4666c5cfda7e5eaff93759florian#endif /* VGA_s390x */ 369933065d4f3548466da4666c5cfda7e5eaff93759florian 370a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian/*------------------------------------------------------------*/ 371a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian/*--- Dirty helper for the "convert unicode" insn family. ---*/ 372a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian/*------------------------------------------------------------*/ 373a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorianvoid 374a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorians390x_dirtyhelper_CUxy(UChar *address, ULong data, ULong num_bytes) 375a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian{ 376a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian UInt i; 377a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 378a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian vassert(num_bytes >= 1 && num_bytes <= 4); 379a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 380a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian /* Store the least significant NUM_BYTES bytes in DATA left to right 381a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian at ADDRESS. */ 382a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian for (i = 1; i <= num_bytes; ++i) { 383a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian address[num_bytes - i] = data & 0xff; 384a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian data >>= 8; 385a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian } 386a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian} 387a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 388a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 389a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian/*------------------------------------------------------------*/ 390a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian/*--- Clean helper for CU21. ---*/ 391a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian/*------------------------------------------------------------*/ 392a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 393a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian/* The function performs a CU21 operation. It returns three things 394a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian encoded in an ULong value: 395a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian - the converted bytes (at most 4) 396a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian - the number of converted bytes 397a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian - an indication whether LOW_SURROGATE, if any, is invalid 398a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 399a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 64 48 16 8 0 400a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian +-------+-----------------+-----------+-----------------------+ 401a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian | 0x0 | converted bytes | num_bytes | invalid_low_surrogate | 402a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian +-------+-----------------+-----------+-----------------------+ 403a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian*/ 404a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorianULong 405a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorians390_do_cu21(UInt srcval, UInt low_surrogate) 406a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian{ 407a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian ULong retval = 0; // shut up gcc 408ae88411aaa8e0b99032fb0bdb04eec21edc54d88florian UInt b1, b2, b3, b4, num_bytes, invalid_low_surrogate = 0; 409a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 410a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian srcval &= 0xffff; 411a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 412a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian /* Determine the number of bytes in the converted value */ 413a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian if (srcval <= 0x007f) 414a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian num_bytes = 1; 415a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian else if (srcval >= 0x0080 && srcval <= 0x07ff) 416a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian num_bytes = 2; 417a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian else if ((srcval >= 0x0800 && srcval <= 0xd7ff) || 418a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian (srcval >= 0xdc00 && srcval <= 0xffff)) 419a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian num_bytes = 3; 420a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian else 421a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian num_bytes = 4; 422a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 423a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian /* Determine UTF-8 bytes according to calculated num_bytes */ 424a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian switch (num_bytes){ 425a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian case 1: 426a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian retval = srcval; 427a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian break; 428a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 429a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian case 2: 430a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian /* order of bytes left to right: b1, b2 */ 431a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b1 = 0xc0; 432a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b1 |= srcval >> 6; 433a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 434a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b2 = 0x80; 435a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b2 |= srcval & 0x3f; 436a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 437a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian retval = (b1 << 8) | b2; 438a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian break; 439a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 440a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian case 3: 441a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian /* order of bytes left to right: b1, b2, b3 */ 442a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b1 = 0xe0; 443a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b1 |= srcval >> 12; 444a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 445a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b2 = 0x80; 446a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b2 |= (srcval >> 6) & 0x3f; 447a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 448a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b3 = 0x80; 449a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b3 |= srcval & 0x3f; 450a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 451a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian retval = (b1 << 16) | (b2 << 8) | b3; 452a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian break; 453a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 454a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian case 4: { 455a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian /* order of bytes left to right: b1, b2, b3, b4 */ 456a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian UInt high_surrogate = srcval; 457a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian UInt uvwxy = ((high_surrogate >> 6) & 0xf) + 1; // abcd + 1 458a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 459a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b1 = 0xf0; 460a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b1 |= uvwxy >> 2; // uvw 461a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 462a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b2 = 0x80; 463a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b2 |= (uvwxy & 0x3) << 4; // xy 464a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b2 |= (high_surrogate >> 2) & 0xf; // efgh 465a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 466a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b3 = 0x80; 467a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b3 |= (high_surrogate & 0x3) << 4; // ij 468a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b3 |= (low_surrogate >> 6) & 0xf; // klmn 469a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 470a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b4 = 0x80; 471a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b4 |= low_surrogate & 0x3f; 472a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 473a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian retval = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4; 474a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 475a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian invalid_low_surrogate = (low_surrogate & 0xfc00) != 0xdc00; 476a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian break; 477a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian } 478a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian } 479a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 480a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian /* At this point RETVAL contains the converted bytes. 481a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian Build up the final return value. */ 482a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian return (retval << 16) | (num_bytes << 8) | invalid_low_surrogate; 483a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian} 484a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 485e711c805f1de40b8fafce36d04e589c6a5074e9aflorian 486e711c805f1de40b8fafce36d04e589c6a5074e9aflorian/*------------------------------------------------------------*/ 4872a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian/*--- Clean helper for CU24. ---*/ 4882a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian/*------------------------------------------------------------*/ 4892a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian 4902a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian/* The function performs a CU24 operation. It returns two things 4912a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian encoded in an ULong value: 4922a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian - the 4 converted bytes 4932a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian - an indication whether LOW_SURROGATE, if any, is invalid 4942a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian 4952a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian 64 40 8 0 4962a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian +------------------------+-----------------------+ 4972a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian | 0x0 | converted bytes | invalid_low_surrogate | 4982a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian +------------------------+-----------------------+ 4992a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian*/ 5002a415a1a1f656e56f88c65f12a37b2658cb45e0bflorianULong 5012a415a1a1f656e56f88c65f12a37b2658cb45e0bflorians390_do_cu24(UInt srcval, UInt low_surrogate) 5022a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian{ 5032a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian ULong retval; 5042a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian UInt invalid_low_surrogate = 0; 5052a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian 5062a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian srcval &= 0xffff; 5072a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian 5082a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian if ((srcval >= 0x0000 && srcval <= 0xd7ff) || 5092a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian (srcval >= 0xdc00 && srcval <= 0xffff)) { 5102a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian retval = srcval; 5112a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian } else { 5122a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian /* D800 - DBFF */ 5132a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian UInt high_surrogate = srcval; 5142a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian UInt uvwxy = ((high_surrogate >> 6) & 0xf) + 1; // abcd + 1 5152a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian UInt efghij = high_surrogate & 0x3f; 5162a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian UInt klmnoprst = low_surrogate & 0x3ff; 5172a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian 5182a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian retval = (uvwxy << 16) | (efghij << 10) | klmnoprst; 5192a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian 5202a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian invalid_low_surrogate = (low_surrogate & 0xfc00) != 0xdc00; 5212a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian } 5222a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian 5232a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian /* At this point RETVAL contains the converted bytes. 5242a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian Build up the final return value. */ 5252a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian return (retval << 8) | invalid_low_surrogate; 5262a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian} 5272a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian 5282a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian 5292a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian/*------------------------------------------------------------*/ 530956194bc1039e9dc43dac4b18ab1fdd5054a5671florian/*--- Clean helper for CU42. ---*/ 531956194bc1039e9dc43dac4b18ab1fdd5054a5671florian/*------------------------------------------------------------*/ 532956194bc1039e9dc43dac4b18ab1fdd5054a5671florian 533956194bc1039e9dc43dac4b18ab1fdd5054a5671florian/* The function performs a CU42 operation. It returns three things 534956194bc1039e9dc43dac4b18ab1fdd5054a5671florian encoded in an ULong value: 535956194bc1039e9dc43dac4b18ab1fdd5054a5671florian - the converted bytes (at most 4) 536956194bc1039e9dc43dac4b18ab1fdd5054a5671florian - the number of converted bytes (2 or 4; 0 if invalid character) 537956194bc1039e9dc43dac4b18ab1fdd5054a5671florian - an indication whether the UTF-32 character is invalid 538956194bc1039e9dc43dac4b18ab1fdd5054a5671florian 539956194bc1039e9dc43dac4b18ab1fdd5054a5671florian 64 48 16 8 0 540956194bc1039e9dc43dac4b18ab1fdd5054a5671florian +-------+-----------------+-----------+-------------------+ 541956194bc1039e9dc43dac4b18ab1fdd5054a5671florian | 0x0 | converted bytes | num_bytes | invalid_character | 542956194bc1039e9dc43dac4b18ab1fdd5054a5671florian +-------+-----------------+-----------+-------------------+ 543956194bc1039e9dc43dac4b18ab1fdd5054a5671florian*/ 544956194bc1039e9dc43dac4b18ab1fdd5054a5671florianULong 545956194bc1039e9dc43dac4b18ab1fdd5054a5671florians390_do_cu42(UInt srcval) 546956194bc1039e9dc43dac4b18ab1fdd5054a5671florian{ 547956194bc1039e9dc43dac4b18ab1fdd5054a5671florian ULong retval; 548956194bc1039e9dc43dac4b18ab1fdd5054a5671florian UInt num_bytes, invalid_character = 0; 549956194bc1039e9dc43dac4b18ab1fdd5054a5671florian 550956194bc1039e9dc43dac4b18ab1fdd5054a5671florian if ((srcval >= 0x0000 && srcval <= 0xd7ff) || 551956194bc1039e9dc43dac4b18ab1fdd5054a5671florian (srcval >= 0xdc00 && srcval <= 0xffff)) { 552956194bc1039e9dc43dac4b18ab1fdd5054a5671florian retval = srcval; 553956194bc1039e9dc43dac4b18ab1fdd5054a5671florian num_bytes = 2; 554956194bc1039e9dc43dac4b18ab1fdd5054a5671florian } else if (srcval >= 0x00010000 && srcval <= 0x0010FFFF) { 555956194bc1039e9dc43dac4b18ab1fdd5054a5671florian UInt uvwxy = srcval >> 16; 556956194bc1039e9dc43dac4b18ab1fdd5054a5671florian UInt abcd = (uvwxy - 1) & 0xf; 557956194bc1039e9dc43dac4b18ab1fdd5054a5671florian UInt efghij = (srcval >> 10) & 0x3f; 558956194bc1039e9dc43dac4b18ab1fdd5054a5671florian 559956194bc1039e9dc43dac4b18ab1fdd5054a5671florian UInt high_surrogate = (0xd8 << 8) | (abcd << 6) | efghij; 560956194bc1039e9dc43dac4b18ab1fdd5054a5671florian UInt low_surrogate = (0xdc << 8) | (srcval & 0x3ff); 561956194bc1039e9dc43dac4b18ab1fdd5054a5671florian 562956194bc1039e9dc43dac4b18ab1fdd5054a5671florian retval = (high_surrogate << 16) | low_surrogate; 563956194bc1039e9dc43dac4b18ab1fdd5054a5671florian num_bytes = 4; 564956194bc1039e9dc43dac4b18ab1fdd5054a5671florian } else { 565956194bc1039e9dc43dac4b18ab1fdd5054a5671florian /* D800 - DBFF or 00110000 - FFFFFFFF */ 566956194bc1039e9dc43dac4b18ab1fdd5054a5671florian invalid_character = 1; 567956194bc1039e9dc43dac4b18ab1fdd5054a5671florian retval = num_bytes = 0; /* does not matter; not used */ 568956194bc1039e9dc43dac4b18ab1fdd5054a5671florian } 569956194bc1039e9dc43dac4b18ab1fdd5054a5671florian 570956194bc1039e9dc43dac4b18ab1fdd5054a5671florian /* At this point RETVAL contains the converted bytes. 571956194bc1039e9dc43dac4b18ab1fdd5054a5671florian Build up the final return value. */ 572956194bc1039e9dc43dac4b18ab1fdd5054a5671florian return (retval << 16) | (num_bytes << 8) | invalid_character; 573956194bc1039e9dc43dac4b18ab1fdd5054a5671florian} 574956194bc1039e9dc43dac4b18ab1fdd5054a5671florian 575956194bc1039e9dc43dac4b18ab1fdd5054a5671florian 576956194bc1039e9dc43dac4b18ab1fdd5054a5671florian/*------------------------------------------------------------*/ 577af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian/*--- Clean helper for CU41. ---*/ 578af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian/*------------------------------------------------------------*/ 579af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian 580af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian/* The function performs a CU41 operation. It returns three things 581af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian encoded in an ULong value: 582af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian - the converted bytes (at most 4) 583af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian - the number of converted bytes (1, 2, 3, or 4; 0 if invalid character) 584af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian - an indication whether the UTF-32 character is invalid 585af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian 586af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian 64 48 16 8 0 587af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian +-------+-----------------+-----------+-------------------+ 588af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian | 0x0 | converted bytes | num_bytes | invalid_character | 589af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian +-------+-----------------+-----------+-------------------+ 590af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian*/ 591af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florianULong 592af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florians390_do_cu41(UInt srcval) 593af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian{ 594af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian ULong retval; 595af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt num_bytes, invalid_character = 0; 596af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian 597af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian if (srcval <= 0x7f) { 598af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian retval = srcval; 599af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian num_bytes = 1; 600af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian } else if (srcval >= 0x80 && srcval <= 0x7ff) { 601af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt fghij = srcval >> 6; 602af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt klmnop = srcval & 0x3f; 603af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt byte1 = (0xc0 | fghij); 604af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt byte2 = (0x80 | klmnop); 605af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian 606af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian retval = (byte1 << 8) | byte2; 607af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian num_bytes = 2; 608af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian } else if ((srcval >= 0x800 && srcval <= 0xd7ff) || 609af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian (srcval >= 0xdc00 && srcval <= 0xffff)) { 610af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt abcd = srcval >> 12; 611af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt efghij = (srcval >> 6) & 0x3f; 612af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt klmnop = srcval & 0x3f; 613af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt byte1 = 0xe0 | abcd; 614af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt byte2 = 0x80 | efghij; 615af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt byte3 = 0x80 | klmnop; 616af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian 617af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian retval = (byte1 << 16) | (byte2 << 8) | byte3; 618af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian num_bytes = 3; 619af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian } else if (srcval >= 0x10000 && srcval <= 0x10ffff) { 620af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt uvw = (srcval >> 18) & 0x7; 621af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt xy = (srcval >> 16) & 0x3; 622af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt efgh = (srcval >> 12) & 0xf; 623af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt ijklmn = (srcval >> 6) & 0x3f; 624af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt opqrst = srcval & 0x3f; 625af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt byte1 = 0xf0 | uvw; 626af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt byte2 = 0x80 | (xy << 4) | efgh; 627af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt byte3 = 0x80 | ijklmn; 628af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt byte4 = 0x80 | opqrst; 629af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian 630af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian retval = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4; 631af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian num_bytes = 4; 632af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian } else { 633af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian /* d800 ... dbff or 00110000 ... ffffffff */ 634af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian invalid_character = 1; 635af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian 636af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian retval = 0; 637af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian num_bytes = 0; 638af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian } 639af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian 640af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian /* At this point RETVAL contains the converted bytes. 641af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian Build up the final return value. */ 642af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian return (retval << 16) | (num_bytes << 8) | invalid_character; 643af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian} 644af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian 645af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian 646af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian/*------------------------------------------------------------*/ 6476d9b9b23ea3541501ea98a39e2d757892a79c78aflorian/*--- Clean helpers for CU12. ---*/ 6486d9b9b23ea3541501ea98a39e2d757892a79c78aflorian/*------------------------------------------------------------*/ 6496d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 6506d9b9b23ea3541501ea98a39e2d757892a79c78aflorian/* The function looks at the first byte of an UTF-8 character and returns 6516d9b9b23ea3541501ea98a39e2d757892a79c78aflorian two things encoded in an ULong value: 6526d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 6536d9b9b23ea3541501ea98a39e2d757892a79c78aflorian - the number of bytes that need to be read 6546d9b9b23ea3541501ea98a39e2d757892a79c78aflorian - an indication whether the UTF-8 character is invalid 6556d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 6566d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 64 16 8 0 6576d9b9b23ea3541501ea98a39e2d757892a79c78aflorian +-------------------+-------------------+ 6586d9b9b23ea3541501ea98a39e2d757892a79c78aflorian | 0x0 | num_bytes | invalid_character | 6596d9b9b23ea3541501ea98a39e2d757892a79c78aflorian +-------+-----------+-------------------+ 6606d9b9b23ea3541501ea98a39e2d757892a79c78aflorian*/ 6616d9b9b23ea3541501ea98a39e2d757892a79c78aflorianULong 6623f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florians390_do_cu12_cu14_helper1(UInt byte, UInt etf3_and_m3_is_1) 6636d9b9b23ea3541501ea98a39e2d757892a79c78aflorian{ 6646d9b9b23ea3541501ea98a39e2d757892a79c78aflorian vassert(byte <= 0xff); 6656d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 6666d9b9b23ea3541501ea98a39e2d757892a79c78aflorian /* Check whether the character is invalid */ 6676d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if (byte >= 0x80 && byte <= 0xbf) return 1; 6686d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if (byte >= 0xf8) return 1; 6696d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 6706d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if (etf3_and_m3_is_1) { 6716d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if (byte == 0xc0 || byte == 0xc1) return 1; 6726d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if (byte >= 0xf5 && byte <= 0xf7) return 1; 6736d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 6746d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 6756d9b9b23ea3541501ea98a39e2d757892a79c78aflorian /* Character is valid */ 6766d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if (byte <= 0x7f) return 1 << 8; // 1 byte 6776d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if (byte <= 0xdf) return 2 << 8; // 2 bytes 6786d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if (byte <= 0xef) return 3 << 8; // 3 bytes 6796d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 6806d9b9b23ea3541501ea98a39e2d757892a79c78aflorian return 4 << 8; // 4 bytes 6816d9b9b23ea3541501ea98a39e2d757892a79c78aflorian} 6826d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 6833f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian/* The function performs a CU12 or CU14 operation. BYTE1, BYTE2, etc are the 6846d9b9b23ea3541501ea98a39e2d757892a79c78aflorian bytes as read from the input stream, left to right. BYTE1 is a valid 6856d9b9b23ea3541501ea98a39e2d757892a79c78aflorian byte. The function returns three things encoded in an ULong value: 6866d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 6876d9b9b23ea3541501ea98a39e2d757892a79c78aflorian - the converted bytes 6886d9b9b23ea3541501ea98a39e2d757892a79c78aflorian - the number of converted bytes (2 or 4; 0 if invalid character) 6896d9b9b23ea3541501ea98a39e2d757892a79c78aflorian - an indication whether the UTF-16 character is invalid 6906d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 6916d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 64 48 16 8 0 6926d9b9b23ea3541501ea98a39e2d757892a79c78aflorian +-------+-----------------+-----------+-------------------+ 6936d9b9b23ea3541501ea98a39e2d757892a79c78aflorian | 0x0 | converted bytes | num_bytes | invalid_character | 6946d9b9b23ea3541501ea98a39e2d757892a79c78aflorian +-------+-----------------+-----------+-------------------+ 6956d9b9b23ea3541501ea98a39e2d757892a79c78aflorian*/ 6963f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florianstatic ULong 6973f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florians390_do_cu12_cu14_helper2(UInt byte1, UInt byte2, UInt byte3, UInt byte4, 6983f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian ULong stuff, Bool is_cu12) 6996d9b9b23ea3541501ea98a39e2d757892a79c78aflorian{ 7003f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian UInt num_src_bytes = stuff >> 1, etf3_and_m3_is_1 = stuff & 0x1; 7016d9b9b23ea3541501ea98a39e2d757892a79c78aflorian UInt num_bytes = 0, invalid_character = 0; 7026d9b9b23ea3541501ea98a39e2d757892a79c78aflorian ULong retval = 0; 7036d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 7046d9b9b23ea3541501ea98a39e2d757892a79c78aflorian vassert(num_src_bytes <= 4); 7056d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 7066d9b9b23ea3541501ea98a39e2d757892a79c78aflorian switch (num_src_bytes) { 7076d9b9b23ea3541501ea98a39e2d757892a79c78aflorian case 1: 7086d9b9b23ea3541501ea98a39e2d757892a79c78aflorian num_bytes = 2; 7096d9b9b23ea3541501ea98a39e2d757892a79c78aflorian retval = byte1; 7106d9b9b23ea3541501ea98a39e2d757892a79c78aflorian break; 7116d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 7126d9b9b23ea3541501ea98a39e2d757892a79c78aflorian case 2: { 7136d9b9b23ea3541501ea98a39e2d757892a79c78aflorian /* Test validity */ 7146d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if (etf3_and_m3_is_1) { 7156d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if (byte2 < 0x80 || byte2 > 0xbf) { 7166d9b9b23ea3541501ea98a39e2d757892a79c78aflorian invalid_character = 1; 7176d9b9b23ea3541501ea98a39e2d757892a79c78aflorian break; 7186d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 7196d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 7206d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 7216d9b9b23ea3541501ea98a39e2d757892a79c78aflorian /* OK */ 7226d9b9b23ea3541501ea98a39e2d757892a79c78aflorian UInt fghij = byte1 & 0x1f; 7236d9b9b23ea3541501ea98a39e2d757892a79c78aflorian UInt klmnop = byte2 & 0x3f; 7246d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 7256d9b9b23ea3541501ea98a39e2d757892a79c78aflorian num_bytes = 2; 7266d9b9b23ea3541501ea98a39e2d757892a79c78aflorian retval = (fghij << 6) | klmnop; 7276d9b9b23ea3541501ea98a39e2d757892a79c78aflorian break; 7286d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 7296d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 7306d9b9b23ea3541501ea98a39e2d757892a79c78aflorian case 3: { 7316d9b9b23ea3541501ea98a39e2d757892a79c78aflorian /* Test validity */ 7326d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if (etf3_and_m3_is_1) { 7336d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if (byte1 == 0xe0) { 7346d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if ((byte2 < 0xa0 || byte2 > 0xbf) || 7356d9b9b23ea3541501ea98a39e2d757892a79c78aflorian (byte3 < 0x80 || byte3 > 0xbf)) { 7366d9b9b23ea3541501ea98a39e2d757892a79c78aflorian invalid_character = 1; 7376d9b9b23ea3541501ea98a39e2d757892a79c78aflorian break; 7386d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 7396d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 7406d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if ((byte1 >= 0xe1 && byte1 <= 0xec) || 7416d9b9b23ea3541501ea98a39e2d757892a79c78aflorian byte1 == 0xee || byte1 == 0xef) { 7426d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if ((byte2 < 0x80 || byte2 > 0xbf) || 7436d9b9b23ea3541501ea98a39e2d757892a79c78aflorian (byte3 < 0x80 || byte3 > 0xbf)) { 7446d9b9b23ea3541501ea98a39e2d757892a79c78aflorian invalid_character = 1; 7456d9b9b23ea3541501ea98a39e2d757892a79c78aflorian break; 7466d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 7476d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 7486d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if (byte1 == 0xed) { 7496d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if ((byte2 < 0x80 || byte2 > 0x9f) || 7506d9b9b23ea3541501ea98a39e2d757892a79c78aflorian (byte3 < 0x80 || byte3 > 0xbf)) { 7516d9b9b23ea3541501ea98a39e2d757892a79c78aflorian invalid_character = 1; 7526d9b9b23ea3541501ea98a39e2d757892a79c78aflorian break; 7536d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 7546d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 7556d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 7566d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 7576d9b9b23ea3541501ea98a39e2d757892a79c78aflorian /* OK */ 7586d9b9b23ea3541501ea98a39e2d757892a79c78aflorian UInt abcd = byte1 & 0xf; 7596d9b9b23ea3541501ea98a39e2d757892a79c78aflorian UInt efghij = byte2 & 0x3f; 7606d9b9b23ea3541501ea98a39e2d757892a79c78aflorian UInt klmnop = byte3 & 0x3f; 7616d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 7626d9b9b23ea3541501ea98a39e2d757892a79c78aflorian num_bytes = 2; 7636d9b9b23ea3541501ea98a39e2d757892a79c78aflorian retval = (abcd << 12) | (efghij << 6) | klmnop; 7646d9b9b23ea3541501ea98a39e2d757892a79c78aflorian break; 7656d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 7666d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 7676d9b9b23ea3541501ea98a39e2d757892a79c78aflorian case 4: { 7686d9b9b23ea3541501ea98a39e2d757892a79c78aflorian /* Test validity */ 7696d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if (etf3_and_m3_is_1) { 7706d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if (byte1 == 0xf0) { 7716d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if ((byte2 < 0x90 || byte2 > 0xbf) || 7726d9b9b23ea3541501ea98a39e2d757892a79c78aflorian (byte3 < 0x80 || byte3 > 0xbf) || 7736d9b9b23ea3541501ea98a39e2d757892a79c78aflorian (byte4 < 0x80 || byte4 > 0xbf)) { 7746d9b9b23ea3541501ea98a39e2d757892a79c78aflorian invalid_character = 1; 7756d9b9b23ea3541501ea98a39e2d757892a79c78aflorian break; 7766d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 7776d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 7786d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if (byte1 == 0xf1 || byte1 == 0xf2 || byte1 == 0xf3) { 7796d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if ((byte2 < 0x80 || byte2 > 0xbf) || 7806d9b9b23ea3541501ea98a39e2d757892a79c78aflorian (byte3 < 0x80 || byte3 > 0xbf) || 7816d9b9b23ea3541501ea98a39e2d757892a79c78aflorian (byte4 < 0x80 || byte4 > 0xbf)) { 7826d9b9b23ea3541501ea98a39e2d757892a79c78aflorian invalid_character = 1; 7836d9b9b23ea3541501ea98a39e2d757892a79c78aflorian break; 7846d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 7856d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 7866d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if (byte1 == 0xf4) { 7876d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if ((byte2 < 0x80 || byte2 > 0x8f) || 7886d9b9b23ea3541501ea98a39e2d757892a79c78aflorian (byte3 < 0x80 || byte3 > 0xbf) || 7896d9b9b23ea3541501ea98a39e2d757892a79c78aflorian (byte4 < 0x80 || byte4 > 0xbf)) { 7906d9b9b23ea3541501ea98a39e2d757892a79c78aflorian invalid_character = 1; 7916d9b9b23ea3541501ea98a39e2d757892a79c78aflorian break; 7926d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 7936d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 7946d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 7956d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 7966d9b9b23ea3541501ea98a39e2d757892a79c78aflorian /* OK */ 7976d9b9b23ea3541501ea98a39e2d757892a79c78aflorian UInt uvw = byte1 & 0x7; 7986d9b9b23ea3541501ea98a39e2d757892a79c78aflorian UInt xy = (byte2 >> 4) & 0x3; 7996d9b9b23ea3541501ea98a39e2d757892a79c78aflorian UInt uvwxy = (uvw << 2) | xy; 8006d9b9b23ea3541501ea98a39e2d757892a79c78aflorian UInt efgh = byte2 & 0xf; 8016d9b9b23ea3541501ea98a39e2d757892a79c78aflorian UInt ij = (byte3 >> 4) & 0x3; 8026d9b9b23ea3541501ea98a39e2d757892a79c78aflorian UInt klmn = byte3 & 0xf; 8036d9b9b23ea3541501ea98a39e2d757892a79c78aflorian UInt opqrst = byte4 & 0x3f; 8046d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 8053f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian if (is_cu12) { 8063f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian UInt abcd = (uvwxy - 1) & 0xf; 8073f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian UInt high_surrogate = (0xd8 << 8) | (abcd << 6) | (efgh << 2) | ij; 8083f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian UInt low_surrogate = (0xdc << 8) | (klmn << 6) | opqrst; 8093f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian 8103f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian num_bytes = 4; 8113f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian retval = (high_surrogate << 16) | low_surrogate; 8123f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian } else { 8133f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian num_bytes = 4; 8143f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian retval = 8153f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian (uvwxy << 16) | (efgh << 12) | (ij << 10) | (klmn << 6) | opqrst; 8163f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian } 8176d9b9b23ea3541501ea98a39e2d757892a79c78aflorian break; 8186d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 8196d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 8206d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 8213f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian if (! is_cu12) num_bytes = 4; // for CU14, by definition 8223f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian 8236d9b9b23ea3541501ea98a39e2d757892a79c78aflorian /* At this point RETVAL contains the converted bytes. 8246d9b9b23ea3541501ea98a39e2d757892a79c78aflorian Build up the final return value. */ 8256d9b9b23ea3541501ea98a39e2d757892a79c78aflorian return (retval << 16) | (num_bytes << 8) | invalid_character; 8266d9b9b23ea3541501ea98a39e2d757892a79c78aflorian} 8276d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 8283f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florianULong 8293f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florians390_do_cu12_helper2(UInt byte1, UInt byte2, UInt byte3, UInt byte4, 8303f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian ULong stuff) 8313f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian{ 8323f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian return s390_do_cu12_cu14_helper2(byte1, byte2, byte3, byte4, stuff, 8333f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian /* is_cu12 = */ 1); 8343f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian} 8353f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian 8363f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florianULong 8373f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florians390_do_cu14_helper2(UInt byte1, UInt byte2, UInt byte3, UInt byte4, 8383f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian ULong stuff) 8393f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian{ 8403f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian return s390_do_cu12_cu14_helper2(byte1, byte2, byte3, byte4, stuff, 8413f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian /* is_cu12 = */ 0); 8423f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian} 8433f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian 8446d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 8456d9b9b23ea3541501ea98a39e2d757892a79c78aflorian/*------------------------------------------------------------*/ 846e711c805f1de40b8fafce36d04e589c6a5074e9aflorian/*--- Clean helper for "convert to binary". ---*/ 847e711c805f1de40b8fafce36d04e589c6a5074e9aflorian/*------------------------------------------------------------*/ 848e711c805f1de40b8fafce36d04e589c6a5074e9aflorian#if defined(VGA_s390x) 849e711c805f1de40b8fafce36d04e589c6a5074e9aflorianUInt 850e711c805f1de40b8fafce36d04e589c6a5074e9aflorians390_do_cvb(ULong decimal) 851e711c805f1de40b8fafce36d04e589c6a5074e9aflorian{ 852e711c805f1de40b8fafce36d04e589c6a5074e9aflorian UInt binary; 853e711c805f1de40b8fafce36d04e589c6a5074e9aflorian 854e711c805f1de40b8fafce36d04e589c6a5074e9aflorian __asm__ volatile ( 855e711c805f1de40b8fafce36d04e589c6a5074e9aflorian "cvb %[result],%[input]\n\t" 856e711c805f1de40b8fafce36d04e589c6a5074e9aflorian : [result] "=d"(binary) 857e711c805f1de40b8fafce36d04e589c6a5074e9aflorian : [input] "m"(decimal) 858e711c805f1de40b8fafce36d04e589c6a5074e9aflorian ); 859e711c805f1de40b8fafce36d04e589c6a5074e9aflorian 860e711c805f1de40b8fafce36d04e589c6a5074e9aflorian return binary; 861e711c805f1de40b8fafce36d04e589c6a5074e9aflorian} 862e711c805f1de40b8fafce36d04e589c6a5074e9aflorian 863e711c805f1de40b8fafce36d04e589c6a5074e9aflorian#else 864e711c805f1de40b8fafce36d04e589c6a5074e9aflorianUInt s390_do_cvb(ULong decimal) { return 0; } 865e711c805f1de40b8fafce36d04e589c6a5074e9aflorian#endif 866e711c805f1de40b8fafce36d04e589c6a5074e9aflorian 867e711c805f1de40b8fafce36d04e589c6a5074e9aflorian 868e711c805f1de40b8fafce36d04e589c6a5074e9aflorian/*------------------------------------------------------------*/ 869e711c805f1de40b8fafce36d04e589c6a5074e9aflorian/*--- Clean helper for "convert to decimal". ---*/ 870e711c805f1de40b8fafce36d04e589c6a5074e9aflorian/*------------------------------------------------------------*/ 871e711c805f1de40b8fafce36d04e589c6a5074e9aflorian#if defined(VGA_s390x) 872e711c805f1de40b8fafce36d04e589c6a5074e9aflorianULong 873e711c805f1de40b8fafce36d04e589c6a5074e9aflorians390_do_cvd(ULong binary_in) 874e711c805f1de40b8fafce36d04e589c6a5074e9aflorian{ 875e711c805f1de40b8fafce36d04e589c6a5074e9aflorian UInt binary = binary_in & 0xffffffffULL; 876e711c805f1de40b8fafce36d04e589c6a5074e9aflorian ULong decimal; 877e711c805f1de40b8fafce36d04e589c6a5074e9aflorian 878e711c805f1de40b8fafce36d04e589c6a5074e9aflorian __asm__ volatile ( 879e711c805f1de40b8fafce36d04e589c6a5074e9aflorian "cvd %[input],%[result]\n\t" 880e711c805f1de40b8fafce36d04e589c6a5074e9aflorian : [result] "=m"(decimal) 881e711c805f1de40b8fafce36d04e589c6a5074e9aflorian : [input] "d"(binary) 882e711c805f1de40b8fafce36d04e589c6a5074e9aflorian ); 883e711c805f1de40b8fafce36d04e589c6a5074e9aflorian 884e711c805f1de40b8fafce36d04e589c6a5074e9aflorian return decimal; 885e711c805f1de40b8fafce36d04e589c6a5074e9aflorian} 886e711c805f1de40b8fafce36d04e589c6a5074e9aflorian 887e711c805f1de40b8fafce36d04e589c6a5074e9aflorian#else 888e711c805f1de40b8fafce36d04e589c6a5074e9aflorianULong s390_do_cvd(ULong binary) { return 0; } 889e711c805f1de40b8fafce36d04e589c6a5074e9aflorian#endif 890e711c805f1de40b8fafce36d04e589c6a5074e9aflorian 8918c88cb6ae821021e1e00be18f5a8bea3c557080aflorian/*------------------------------------------------------------*/ 8928c88cb6ae821021e1e00be18f5a8bea3c557080aflorian/*--- Clean helper for "Extract cache attribute". ---*/ 8938c88cb6ae821021e1e00be18f5a8bea3c557080aflorian/*------------------------------------------------------------*/ 8948c88cb6ae821021e1e00be18f5a8bea3c557080aflorian#if defined(VGA_s390x) 8958c88cb6ae821021e1e00be18f5a8bea3c557080aflorianULong 8968c88cb6ae821021e1e00be18f5a8bea3c557080aflorians390_do_ecag(ULong op2addr) 8978c88cb6ae821021e1e00be18f5a8bea3c557080aflorian{ 8988c88cb6ae821021e1e00be18f5a8bea3c557080aflorian ULong result; 8998c88cb6ae821021e1e00be18f5a8bea3c557080aflorian 9008c88cb6ae821021e1e00be18f5a8bea3c557080aflorian __asm__ volatile(".insn rsy,0xEB000000004C,%[out],0,0(%[in])\n\t" 9018c88cb6ae821021e1e00be18f5a8bea3c557080aflorian : [out] "=d"(result) 9028c88cb6ae821021e1e00be18f5a8bea3c557080aflorian : [in] "d"(op2addr)); 9038c88cb6ae821021e1e00be18f5a8bea3c557080aflorian return result; 9048c88cb6ae821021e1e00be18f5a8bea3c557080aflorian} 9058c88cb6ae821021e1e00be18f5a8bea3c557080aflorian 9068c88cb6ae821021e1e00be18f5a8bea3c557080aflorian#else 9078c88cb6ae821021e1e00be18f5a8bea3c557080aflorianULong s390_do_ecag(ULong op2addr) { return 0; } 9088c88cb6ae821021e1e00be18f5a8bea3c557080aflorian#endif 909e711c805f1de40b8fafce36d04e589c6a5074e9aflorian 910933065d4f3548466da4666c5cfda7e5eaff93759florian/*------------------------------------------------------------*/ 91178d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian/*--- Clean helper for "Perform Floating Point Operation". ---*/ 91278d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian/*------------------------------------------------------------*/ 91378d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian#if defined(VGA_s390x) 91478d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florianUInt 91578d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florians390_do_pfpo(UInt gpr0) 91678d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian{ 91778d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian UChar rm; 91878d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian UChar op1_ty, op2_ty; 91978d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian 92078d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian rm = gpr0 & 0xf; 92178d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian if (rm > 1 && rm < 8) 92278d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian return EmFail_S390X_invalid_PFPO_rounding_mode; 92378d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian 92478d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian op1_ty = (gpr0 >> 16) & 0xff; // gpr0[40:47] 92578d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian op2_ty = (gpr0 >> 8) & 0xff; // gpr0[48:55] 92678d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian /* Operand type must be BFP 32, 64, 128 or DFP 32, 64, 128 92778d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian which correspond to 0x5, 0x6, 0x7, 0x8, 0x9, 0xa respectively. 92878d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian Any other operand type value is unsupported */ 92978d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian if ((op1_ty == op2_ty) || 93078d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian (op1_ty < 0x5 || op1_ty > 0xa) || 93178d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian (op2_ty < 0x5 || op2_ty > 0xa)) 93278d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian return EmFail_S390X_invalid_PFPO_function; 93378d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian 93478d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian return EmNote_NONE; 93578d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian} 93678d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian#else 93778d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florianUInt s390_do_pfpo(UInt gpr0) { return 0; } 93878d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian#endif 93978d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian 94078d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian/*------------------------------------------------------------*/ 9412019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*--- Helper for condition code. ---*/ 9422019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*------------------------------------------------------------*/ 9432019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 94483f60b5fac7ad065935f3c2fcf7b1454d552d6e0florian/* Convert an IRRoundingMode value to s390_bfp_round_t */ 9453d80fade93ec633f3ad30f871d1a1306f75823c6florian#if defined(VGA_s390x) 946125e20dc4036944b19bed3e98a15d05cce8c29f6florianstatic s390_bfp_round_t 94719e0077d31fe17496eeb76cd008507d1a8f75908floriandecode_bfp_rounding_mode(UInt irrm) 94819e0077d31fe17496eeb76cd008507d1a8f75908florian{ 94919e0077d31fe17496eeb76cd008507d1a8f75908florian switch (irrm) { 950125e20dc4036944b19bed3e98a15d05cce8c29f6florian case Irrm_NEAREST: return S390_BFP_ROUND_NEAREST_EVEN; 951125e20dc4036944b19bed3e98a15d05cce8c29f6florian case Irrm_NegINF: return S390_BFP_ROUND_NEGINF; 952125e20dc4036944b19bed3e98a15d05cce8c29f6florian case Irrm_PosINF: return S390_BFP_ROUND_POSINF; 953125e20dc4036944b19bed3e98a15d05cce8c29f6florian case Irrm_ZERO: return S390_BFP_ROUND_ZERO; 95419e0077d31fe17496eeb76cd008507d1a8f75908florian } 95519e0077d31fe17496eeb76cd008507d1a8f75908florian vpanic("decode_bfp_rounding_mode"); 95619e0077d31fe17496eeb76cd008507d1a8f75908florian} 9573d80fade93ec633f3ad30f871d1a1306f75823c6florian#endif 95819e0077d31fe17496eeb76cd008507d1a8f75908florian 95919e0077d31fe17496eeb76cd008507d1a8f75908florian 9602019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#define S390_CC_FOR_BINARY(opcode,cc_dep1,cc_dep2) \ 9612019a976f07ff418dde2dfc7cc74667ef66d7764sewardj({ \ 9622019a976f07ff418dde2dfc7cc74667ef66d7764sewardj __asm__ volatile ( \ 9632019a976f07ff418dde2dfc7cc74667ef66d7764sewardj opcode " %[op1],%[op2]\n\t" \ 9642019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ipm %[psw]\n\t" : [psw] "=d"(psw), [op1] "+d"(cc_dep1) \ 9652019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : [op2] "d"(cc_dep2) \ 9662019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : "cc");\ 9672019a976f07ff418dde2dfc7cc74667ef66d7764sewardj psw >> 28; /* cc */ \ 9682019a976f07ff418dde2dfc7cc74667ef66d7764sewardj}) 9692019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 9702019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#define S390_CC_FOR_TERNARY_SUBB(opcode,cc_dep1,cc_dep2,cc_ndep) \ 9712019a976f07ff418dde2dfc7cc74667ef66d7764sewardj({ \ 9722019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Recover the original DEP2 value. See comment near s390_cc_thunk_put3 \ 9732019a976f07ff418dde2dfc7cc74667ef66d7764sewardj for rationale. */ \ 9742019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc_dep2 = cc_dep2 ^ cc_ndep; \ 9752019a976f07ff418dde2dfc7cc74667ef66d7764sewardj __asm__ volatile ( \ 9762019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "lghi 0,1\n\t" \ 9772019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "sr 0,%[op3]\n\t" /* borrow to cc */ \ 9782019a976f07ff418dde2dfc7cc74667ef66d7764sewardj opcode " %[op1],%[op2]\n\t" /* then redo the op */\ 9792019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ipm %[psw]\n\t" : [psw] "=d"(psw), [op1] "+&d"(cc_dep1) \ 9802019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : [op2] "d"(cc_dep2), [op3] "d"(cc_ndep) \ 9812019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : "0", "cc");\ 9822019a976f07ff418dde2dfc7cc74667ef66d7764sewardj psw >> 28; /* cc */ \ 9832019a976f07ff418dde2dfc7cc74667ef66d7764sewardj}) 9842019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 9852019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#define S390_CC_FOR_TERNARY_ADDC(opcode,cc_dep1,cc_dep2,cc_ndep) \ 9862019a976f07ff418dde2dfc7cc74667ef66d7764sewardj({ \ 9872019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Recover the original DEP2 value. See comment near s390_cc_thunk_put3 \ 9882019a976f07ff418dde2dfc7cc74667ef66d7764sewardj for rationale. */ \ 9892019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc_dep2 = cc_dep2 ^ cc_ndep; \ 9902019a976f07ff418dde2dfc7cc74667ef66d7764sewardj __asm__ volatile ( \ 9912019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "lgfr 0,%[op3]\n\t" /* first load cc_ndep */ \ 9922019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "aghi 0,0\n\t" /* and convert it into a cc */ \ 9932019a976f07ff418dde2dfc7cc74667ef66d7764sewardj opcode " %[op1],%[op2]\n\t" /* then redo the op */\ 9942019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ipm %[psw]\n\t" : [psw] "=d"(psw), [op1] "+&d"(cc_dep1) \ 9952019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : [op2] "d"(cc_dep2), [op3] "d"(cc_ndep) \ 9962019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : "0", "cc");\ 9972019a976f07ff418dde2dfc7cc74667ef66d7764sewardj psw >> 28; /* cc */ \ 9982019a976f07ff418dde2dfc7cc74667ef66d7764sewardj}) 9992019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 10002019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 10012019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#define S390_CC_FOR_BFP_RESULT(opcode,cc_dep1) \ 10022019a976f07ff418dde2dfc7cc74667ef66d7764sewardj({ \ 10032019a976f07ff418dde2dfc7cc74667ef66d7764sewardj __asm__ volatile ( \ 10042019a976f07ff418dde2dfc7cc74667ef66d7764sewardj opcode " 0,%[op]\n\t" \ 10052019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ipm %[psw]\n\t" : [psw] "=d"(psw) \ 10062019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : [op] "f"(cc_dep1) \ 10072019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : "cc", "f0");\ 10082019a976f07ff418dde2dfc7cc74667ef66d7764sewardj psw >> 28; /* cc */ \ 10092019a976f07ff418dde2dfc7cc74667ef66d7764sewardj}) 10102019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 10112019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#define S390_CC_FOR_BFP128_RESULT(hi,lo) \ 10122019a976f07ff418dde2dfc7cc74667ef66d7764sewardj({ \ 10132019a976f07ff418dde2dfc7cc74667ef66d7764sewardj __asm__ volatile ( \ 10142019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ldr 4,%[high]\n\t" \ 10152019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ldr 6,%[low]\n\t" \ 10162019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ltxbr 0,4\n\t" \ 10172019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ipm %[psw]\n\t" : [psw] "=d"(psw) \ 10182019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : [high] "f"(hi), [low] "f"(lo) \ 10192019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : "cc", "f0", "f2", "f4", "f6");\ 10202019a976f07ff418dde2dfc7cc74667ef66d7764sewardj psw >> 28; /* cc */ \ 10212019a976f07ff418dde2dfc7cc74667ef66d7764sewardj}) 10222019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 102319e0077d31fe17496eeb76cd008507d1a8f75908florian#define S390_CC_FOR_BFP_CONVERT_AUX(opcode,cc_dep1,rounding_mode) \ 10242019a976f07ff418dde2dfc7cc74667ef66d7764sewardj({ \ 10252019a976f07ff418dde2dfc7cc74667ef66d7764sewardj __asm__ volatile ( \ 102619e0077d31fe17496eeb76cd008507d1a8f75908florian opcode " 0," #rounding_mode ",%[op]\n\t" \ 10272019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ipm %[psw]\n\t" : [psw] "=d"(psw) \ 10282019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : [op] "f"(cc_dep1) \ 10292019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : "cc", "r0");\ 10302019a976f07ff418dde2dfc7cc74667ef66d7764sewardj psw >> 28; /* cc */ \ 10312019a976f07ff418dde2dfc7cc74667ef66d7764sewardj}) 10322019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 103319e0077d31fe17496eeb76cd008507d1a8f75908florian#define S390_CC_FOR_BFP_CONVERT(opcode,cc_dep1,cc_dep2) \ 103419e0077d31fe17496eeb76cd008507d1a8f75908florian({ \ 103519e0077d31fe17496eeb76cd008507d1a8f75908florian UInt cc; \ 103619e0077d31fe17496eeb76cd008507d1a8f75908florian switch (decode_bfp_rounding_mode(cc_dep2)) { \ 1037125e20dc4036944b19bed3e98a15d05cce8c29f6florian case S390_BFP_ROUND_NEAREST_EVEN: \ 103819e0077d31fe17496eeb76cd008507d1a8f75908florian cc = S390_CC_FOR_BFP_CONVERT_AUX(opcode,cc_dep1,4); \ 103919e0077d31fe17496eeb76cd008507d1a8f75908florian break; \ 1040125e20dc4036944b19bed3e98a15d05cce8c29f6florian case S390_BFP_ROUND_ZERO: \ 104119e0077d31fe17496eeb76cd008507d1a8f75908florian cc = S390_CC_FOR_BFP_CONVERT_AUX(opcode,cc_dep1,5); \ 104219e0077d31fe17496eeb76cd008507d1a8f75908florian break; \ 1043125e20dc4036944b19bed3e98a15d05cce8c29f6florian case S390_BFP_ROUND_POSINF: \ 104419e0077d31fe17496eeb76cd008507d1a8f75908florian cc = S390_CC_FOR_BFP_CONVERT_AUX(opcode,cc_dep1,6); \ 104519e0077d31fe17496eeb76cd008507d1a8f75908florian break; \ 1046125e20dc4036944b19bed3e98a15d05cce8c29f6florian case S390_BFP_ROUND_NEGINF: \ 104719e0077d31fe17496eeb76cd008507d1a8f75908florian cc = S390_CC_FOR_BFP_CONVERT_AUX(opcode,cc_dep1,7); \ 104819e0077d31fe17496eeb76cd008507d1a8f75908florian break; \ 104919e0077d31fe17496eeb76cd008507d1a8f75908florian default: \ 1050125e20dc4036944b19bed3e98a15d05cce8c29f6florian vpanic("unexpected bfp rounding mode"); \ 105119e0077d31fe17496eeb76cd008507d1a8f75908florian } \ 105219e0077d31fe17496eeb76cd008507d1a8f75908florian cc; \ 105319e0077d31fe17496eeb76cd008507d1a8f75908florian}) 105419e0077d31fe17496eeb76cd008507d1a8f75908florian 105519e0077d31fe17496eeb76cd008507d1a8f75908florian#define S390_CC_FOR_BFP_UCONVERT_AUX(opcode,cc_dep1,rounding_mode) \ 10561c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian({ \ 10571c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian __asm__ volatile ( \ 105819e0077d31fe17496eeb76cd008507d1a8f75908florian opcode ",0,%[op]," #rounding_mode ",0\n\t" \ 10591c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian "ipm %[psw]\n\t" : [psw] "=d"(psw) \ 10601c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian : [op] "f"(cc_dep1) \ 10611c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian : "cc", "r0");\ 10621c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian psw >> 28; /* cc */ \ 10631c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian}) 10641c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian 106519e0077d31fe17496eeb76cd008507d1a8f75908florian#define S390_CC_FOR_BFP_UCONVERT(opcode,cc_dep1,cc_dep2) \ 106619e0077d31fe17496eeb76cd008507d1a8f75908florian({ \ 106719e0077d31fe17496eeb76cd008507d1a8f75908florian UInt cc; \ 106819e0077d31fe17496eeb76cd008507d1a8f75908florian switch (decode_bfp_rounding_mode(cc_dep2)) { \ 1069125e20dc4036944b19bed3e98a15d05cce8c29f6florian case S390_BFP_ROUND_NEAREST_EVEN: \ 107019e0077d31fe17496eeb76cd008507d1a8f75908florian cc = S390_CC_FOR_BFP_UCONVERT_AUX(opcode,cc_dep1,4); \ 107119e0077d31fe17496eeb76cd008507d1a8f75908florian break; \ 1072125e20dc4036944b19bed3e98a15d05cce8c29f6florian case S390_BFP_ROUND_ZERO: \ 107319e0077d31fe17496eeb76cd008507d1a8f75908florian cc = S390_CC_FOR_BFP_UCONVERT_AUX(opcode,cc_dep1,5); \ 107419e0077d31fe17496eeb76cd008507d1a8f75908florian break; \ 1075125e20dc4036944b19bed3e98a15d05cce8c29f6florian case S390_BFP_ROUND_POSINF: \ 107619e0077d31fe17496eeb76cd008507d1a8f75908florian cc = S390_CC_FOR_BFP_UCONVERT_AUX(opcode,cc_dep1,6); \ 107719e0077d31fe17496eeb76cd008507d1a8f75908florian break; \ 1078125e20dc4036944b19bed3e98a15d05cce8c29f6florian case S390_BFP_ROUND_NEGINF: \ 107919e0077d31fe17496eeb76cd008507d1a8f75908florian cc = S390_CC_FOR_BFP_UCONVERT_AUX(opcode,cc_dep1,7); \ 108019e0077d31fe17496eeb76cd008507d1a8f75908florian break; \ 108119e0077d31fe17496eeb76cd008507d1a8f75908florian default: \ 1082125e20dc4036944b19bed3e98a15d05cce8c29f6florian vpanic("unexpected bfp rounding mode"); \ 108319e0077d31fe17496eeb76cd008507d1a8f75908florian } \ 108419e0077d31fe17496eeb76cd008507d1a8f75908florian cc; \ 108519e0077d31fe17496eeb76cd008507d1a8f75908florian}) 108619e0077d31fe17496eeb76cd008507d1a8f75908florian 108719e0077d31fe17496eeb76cd008507d1a8f75908florian#define S390_CC_FOR_BFP128_CONVERT_AUX(opcode,hi,lo,rounding_mode) \ 10882019a976f07ff418dde2dfc7cc74667ef66d7764sewardj({ \ 10892019a976f07ff418dde2dfc7cc74667ef66d7764sewardj __asm__ volatile ( \ 10902019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ldr 4,%[high]\n\t" \ 10912019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ldr 6,%[low]\n\t" \ 109219e0077d31fe17496eeb76cd008507d1a8f75908florian opcode " 0," #rounding_mode ",4\n\t" \ 10932019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ipm %[psw]\n\t" : [psw] "=d"(psw) \ 10942019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : [high] "f"(hi), [low] "f"(lo) \ 10952019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : "cc", "r0", "f4", "f6");\ 10962019a976f07ff418dde2dfc7cc74667ef66d7764sewardj psw >> 28; /* cc */ \ 10972019a976f07ff418dde2dfc7cc74667ef66d7764sewardj}) 10982019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 109919e0077d31fe17496eeb76cd008507d1a8f75908florian#define S390_CC_FOR_BFP128_CONVERT(opcode,cc_dep1,cc_dep2,cc_ndep) \ 110019e0077d31fe17496eeb76cd008507d1a8f75908florian({ \ 110119e0077d31fe17496eeb76cd008507d1a8f75908florian UInt cc; \ 110219e0077d31fe17496eeb76cd008507d1a8f75908florian /* Recover the original DEP2 value. See comment near \ 110319e0077d31fe17496eeb76cd008507d1a8f75908florian s390_cc_thunk_put3 for rationale. */ \ 110419e0077d31fe17496eeb76cd008507d1a8f75908florian cc_dep2 = cc_dep2 ^ cc_ndep; \ 110519e0077d31fe17496eeb76cd008507d1a8f75908florian switch (decode_bfp_rounding_mode(cc_ndep)) { \ 1106125e20dc4036944b19bed3e98a15d05cce8c29f6florian case S390_BFP_ROUND_NEAREST_EVEN: \ 110719e0077d31fe17496eeb76cd008507d1a8f75908florian cc = S390_CC_FOR_BFP128_CONVERT_AUX(opcode,cc_dep1,cc_dep2,4); \ 110819e0077d31fe17496eeb76cd008507d1a8f75908florian break; \ 1109125e20dc4036944b19bed3e98a15d05cce8c29f6florian case S390_BFP_ROUND_ZERO: \ 111019e0077d31fe17496eeb76cd008507d1a8f75908florian cc = S390_CC_FOR_BFP128_CONVERT_AUX(opcode,cc_dep1,cc_dep2,5); \ 111119e0077d31fe17496eeb76cd008507d1a8f75908florian break; \ 1112125e20dc4036944b19bed3e98a15d05cce8c29f6florian case S390_BFP_ROUND_POSINF: \ 111319e0077d31fe17496eeb76cd008507d1a8f75908florian cc = S390_CC_FOR_BFP128_CONVERT_AUX(opcode,cc_dep1,cc_dep2,6); \ 111419e0077d31fe17496eeb76cd008507d1a8f75908florian break; \ 1115125e20dc4036944b19bed3e98a15d05cce8c29f6florian case S390_BFP_ROUND_NEGINF: \ 111619e0077d31fe17496eeb76cd008507d1a8f75908florian cc = S390_CC_FOR_BFP128_CONVERT_AUX(opcode,cc_dep1,cc_dep2,7); \ 111719e0077d31fe17496eeb76cd008507d1a8f75908florian break; \ 111819e0077d31fe17496eeb76cd008507d1a8f75908florian default: \ 1119125e20dc4036944b19bed3e98a15d05cce8c29f6florian vpanic("unexpected bfp rounding mode"); \ 112019e0077d31fe17496eeb76cd008507d1a8f75908florian } \ 112119e0077d31fe17496eeb76cd008507d1a8f75908florian cc; \ 112219e0077d31fe17496eeb76cd008507d1a8f75908florian}) 112319e0077d31fe17496eeb76cd008507d1a8f75908florian 112419e0077d31fe17496eeb76cd008507d1a8f75908florian#define S390_CC_FOR_BFP128_UCONVERT_AUX(opcode,hi,lo,rounding_mode) \ 11251c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian({ \ 11261c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian __asm__ volatile ( \ 11271c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian "ldr 4,%[high]\n\t" \ 11281c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian "ldr 6,%[low]\n\t" \ 112919e0077d31fe17496eeb76cd008507d1a8f75908florian opcode ",0,4," #rounding_mode ",0\n\t" \ 11301c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian "ipm %[psw]\n\t" : [psw] "=d"(psw) \ 11311c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian : [high] "f"(hi), [low] "f"(lo) \ 11321c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian : "cc", "r0", "f4", "f6");\ 11331c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian psw >> 28; /* cc */ \ 11341c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian}) 11351c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian 113619e0077d31fe17496eeb76cd008507d1a8f75908florian#define S390_CC_FOR_BFP128_UCONVERT(opcode,cc_dep1,cc_dep2,cc_ndep) \ 113719e0077d31fe17496eeb76cd008507d1a8f75908florian({ \ 113819e0077d31fe17496eeb76cd008507d1a8f75908florian UInt cc; \ 113919e0077d31fe17496eeb76cd008507d1a8f75908florian /* Recover the original DEP2 value. See comment near \ 114019e0077d31fe17496eeb76cd008507d1a8f75908florian s390_cc_thunk_put3 for rationale. */ \ 114119e0077d31fe17496eeb76cd008507d1a8f75908florian cc_dep2 = cc_dep2 ^ cc_ndep; \ 114219e0077d31fe17496eeb76cd008507d1a8f75908florian switch (decode_bfp_rounding_mode(cc_ndep)) { \ 1143125e20dc4036944b19bed3e98a15d05cce8c29f6florian case S390_BFP_ROUND_NEAREST_EVEN: \ 114419e0077d31fe17496eeb76cd008507d1a8f75908florian cc = S390_CC_FOR_BFP128_UCONVERT_AUX(opcode,cc_dep1,cc_dep2,4); \ 114519e0077d31fe17496eeb76cd008507d1a8f75908florian break; \ 1146125e20dc4036944b19bed3e98a15d05cce8c29f6florian case S390_BFP_ROUND_ZERO: \ 114719e0077d31fe17496eeb76cd008507d1a8f75908florian cc = S390_CC_FOR_BFP128_UCONVERT_AUX(opcode,cc_dep1,cc_dep2,5); \ 114819e0077d31fe17496eeb76cd008507d1a8f75908florian break; \ 1149125e20dc4036944b19bed3e98a15d05cce8c29f6florian case S390_BFP_ROUND_POSINF: \ 115019e0077d31fe17496eeb76cd008507d1a8f75908florian cc = S390_CC_FOR_BFP128_UCONVERT_AUX(opcode,cc_dep1,cc_dep2,6); \ 115119e0077d31fe17496eeb76cd008507d1a8f75908florian break; \ 1152125e20dc4036944b19bed3e98a15d05cce8c29f6florian case S390_BFP_ROUND_NEGINF: \ 115319e0077d31fe17496eeb76cd008507d1a8f75908florian cc = S390_CC_FOR_BFP128_UCONVERT_AUX(opcode,cc_dep1,cc_dep2,7); \ 115419e0077d31fe17496eeb76cd008507d1a8f75908florian break; \ 115519e0077d31fe17496eeb76cd008507d1a8f75908florian default: \ 1156125e20dc4036944b19bed3e98a15d05cce8c29f6florian vpanic("unexpected bfp rounding mode"); \ 115719e0077d31fe17496eeb76cd008507d1a8f75908florian } \ 115819e0077d31fe17496eeb76cd008507d1a8f75908florian cc; \ 115919e0077d31fe17496eeb76cd008507d1a8f75908florian}) 116019e0077d31fe17496eeb76cd008507d1a8f75908florian 11612019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#define S390_CC_FOR_BFP_TDC(opcode,cc_dep1,cc_dep2) \ 11622019a976f07ff418dde2dfc7cc74667ef66d7764sewardj({ \ 11632019a976f07ff418dde2dfc7cc74667ef66d7764sewardj __asm__ volatile ( \ 11642019a976f07ff418dde2dfc7cc74667ef66d7764sewardj opcode " %[value],0(%[class])\n\t" \ 11652019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ipm %[psw]\n\t" : [psw] "=d"(psw) \ 11662019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : [value] "f"(cc_dep1), \ 11672019a976f07ff418dde2dfc7cc74667ef66d7764sewardj [class] "a"(cc_dep2) \ 11682019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : "cc");\ 11692019a976f07ff418dde2dfc7cc74667ef66d7764sewardj psw >> 28; /* cc */ \ 11702019a976f07ff418dde2dfc7cc74667ef66d7764sewardj}) 11712019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 11722019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#define S390_CC_FOR_BFP128_TDC(cc_dep1,cc_dep2,cc_ndep) \ 11732019a976f07ff418dde2dfc7cc74667ef66d7764sewardj({ \ 1174cf1527c8f8a8a647cae5ef21b6b126db9b81f622florian /* Recover the original DEP2 value. See comment near \ 1175cf1527c8f8a8a647cae5ef21b6b126db9b81f622florian s390_cc_thunk_put1f128Z for rationale. */ \ 11762019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc_dep2 = cc_dep2 ^ cc_ndep; \ 11772019a976f07ff418dde2dfc7cc74667ef66d7764sewardj __asm__ volatile ( \ 11782019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ldr 4,%[high]\n\t" \ 11792019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ldr 6,%[low]\n\t" \ 11802019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "tcxb 4,0(%[class])\n\t" \ 11812019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ipm %[psw]\n\t" : [psw] "=d"(psw) \ 11822019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : [high] "f"(cc_dep1), [low] "f"(cc_dep2), \ 11832019a976f07ff418dde2dfc7cc74667ef66d7764sewardj [class] "a"(cc_ndep) \ 11842019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : "cc", "f4", "f6");\ 11852019a976f07ff418dde2dfc7cc74667ef66d7764sewardj psw >> 28; /* cc */ \ 11862019a976f07ff418dde2dfc7cc74667ef66d7764sewardj}) 11872019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 118879e5a4845df6d09250b142c4e160a95cf7688fc8florian/* Convert an IRRoundingMode value to s390_dfp_round_t */ 11895f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian#if defined(VGA_s390x) 11905f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florianstatic s390_dfp_round_t 11915f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3floriandecode_dfp_rounding_mode(UInt irrm) 11925f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian{ 11935f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian switch (irrm) { 119479e5a4845df6d09250b142c4e160a95cf7688fc8florian case Irrm_NEAREST: 11955f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian return S390_DFP_ROUND_NEAREST_EVEN_4; 119679e5a4845df6d09250b142c4e160a95cf7688fc8florian case Irrm_NegINF: 11975f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian return S390_DFP_ROUND_NEGINF_7; 119879e5a4845df6d09250b142c4e160a95cf7688fc8florian case Irrm_PosINF: 11995f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian return S390_DFP_ROUND_POSINF_6; 120079e5a4845df6d09250b142c4e160a95cf7688fc8florian case Irrm_ZERO: 12015f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian return S390_DFP_ROUND_ZERO_5; 120279e5a4845df6d09250b142c4e160a95cf7688fc8florian case Irrm_NEAREST_TIE_AWAY_0: 12035f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian return S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1; 120479e5a4845df6d09250b142c4e160a95cf7688fc8florian case Irrm_PREPARE_SHORTER: 12055f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian return S390_DFP_ROUND_PREPARE_SHORT_3; 120679e5a4845df6d09250b142c4e160a95cf7688fc8florian case Irrm_AWAY_FROM_ZERO: 12075f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian return S390_DFP_ROUND_AWAY_0; 120879e5a4845df6d09250b142c4e160a95cf7688fc8florian case Irrm_NEAREST_TIE_TOWARD_0: 12095f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian return S390_DFP_ROUND_NEAREST_TIE_TOWARD_0; 12105f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian } 12115f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian vpanic("decode_dfp_rounding_mode"); 12125f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian} 12135f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian#endif 12145f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian 12151239020c948a6e20faaa8d0fa5dea44302e18f8aflorian#define S390_CC_FOR_DFP_RESULT(cc_dep1) \ 12161239020c948a6e20faaa8d0fa5dea44302e18f8aflorian({ \ 12171239020c948a6e20faaa8d0fa5dea44302e18f8aflorian __asm__ volatile ( \ 12181239020c948a6e20faaa8d0fa5dea44302e18f8aflorian ".insn rre, 0xb3d60000,0,%[op]\n\t" /* LTDTR */ \ 12191239020c948a6e20faaa8d0fa5dea44302e18f8aflorian "ipm %[psw]\n\t" : [psw] "=d"(psw) \ 12201239020c948a6e20faaa8d0fa5dea44302e18f8aflorian : [op] "f"(cc_dep1) \ 12211239020c948a6e20faaa8d0fa5dea44302e18f8aflorian : "cc", "f0"); \ 12221239020c948a6e20faaa8d0fa5dea44302e18f8aflorian psw >> 28; /* cc */ \ 12231239020c948a6e20faaa8d0fa5dea44302e18f8aflorian}) 12241239020c948a6e20faaa8d0fa5dea44302e18f8aflorian 1225e38f641461120ea338069a3f45820168959968abflorian#define S390_CC_FOR_DFP128_RESULT(hi,lo) \ 1226e38f641461120ea338069a3f45820168959968abflorian({ \ 1227e38f641461120ea338069a3f45820168959968abflorian __asm__ volatile ( \ 1228cf1527c8f8a8a647cae5ef21b6b126db9b81f622florian "ldr 4,%[high]\n\t" \ 1229cf1527c8f8a8a647cae5ef21b6b126db9b81f622florian "ldr 6,%[low]\n\t" \ 1230cf1527c8f8a8a647cae5ef21b6b126db9b81f622florian ".insn rre, 0xb3de0000,0,4\n\t" /* LTXTR */ \ 1231cf1527c8f8a8a647cae5ef21b6b126db9b81f622florian "ipm %[psw]\n\t" : [psw] "=d"(psw) \ 1232cf1527c8f8a8a647cae5ef21b6b126db9b81f622florian : [high] "f"(hi), [low] "f"(lo) \ 1233cf1527c8f8a8a647cae5ef21b6b126db9b81f622florian : "cc", "f0", "f2", "f4", "f6"); \ 1234e38f641461120ea338069a3f45820168959968abflorian psw >> 28; /* cc */ \ 1235e38f641461120ea338069a3f45820168959968abflorian}) 1236e38f641461120ea338069a3f45820168959968abflorian 1237ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian#define S390_CC_FOR_DFP_TD(opcode,cc_dep1,cc_dep2) \ 1238ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian({ \ 1239ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian __asm__ volatile ( \ 1240ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian opcode ",%[value],0(%[class])\n\t" \ 1241ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian "ipm %[psw]\n\t" : [psw] "=d"(psw) \ 1242ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian : [value] "f"(cc_dep1), \ 1243ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian [class] "a"(cc_dep2) \ 1244ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian : "cc"); \ 1245ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian psw >> 28; /* cc */ \ 1246ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian}) 1247ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian 1248ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian#define S390_CC_FOR_DFP128_TD(opcode,cc_dep1,cc_dep2,cc_ndep) \ 1249ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian({ \ 1250ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian /* Recover the original DEP2 value. See comment near \ 1251ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian s390_cc_thunk_put1d128Z for rationale. */ \ 1252ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian cc_dep2 = cc_dep2 ^ cc_ndep; \ 1253ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian __asm__ volatile ( \ 1254ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian "ldr 4,%[high]\n\t" \ 1255ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian "ldr 6,%[low]\n\t" \ 1256ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian opcode ",4,0(%[class])\n\t" \ 1257ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian "ipm %[psw]\n\t" : [psw] "=d"(psw) \ 1258ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian : [high] "f"(cc_dep1), [low] "f"(cc_dep2), \ 1259ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian [class] "a"(cc_ndep) \ 1260ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian : "cc", "f4", "f6"); \ 1261ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian psw >> 28; /* cc */ \ 1262ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian}) 1263ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian 12645f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian#define S390_CC_FOR_DFP_CONVERT_AUX(opcode,cc_dep1,rounding_mode) \ 12655f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian ({ \ 12665f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian __asm__ volatile ( \ 12675f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian opcode ",0,%[op]," #rounding_mode ",0\n\t" \ 12685f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian "ipm %[psw]\n\t" : [psw] "=d"(psw) \ 12695f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian : [op] "f"(cc_dep1) \ 12705f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian : "cc", "r0"); \ 12715f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian psw >> 28; /* cc */ \ 12725f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian }) 12735f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian 12745f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian#define S390_CC_FOR_DFP_CONVERT(opcode,cc_dep1,cc_dep2) \ 12755f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian ({ \ 12765f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian UInt cc; \ 12775f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian switch (decode_dfp_rounding_mode(cc_dep2)) { \ 12785f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1: \ 12795f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12: \ 12805f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP_CONVERT_AUX(opcode,cc_dep1,1); \ 12815f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 12825f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_PREPARE_SHORT_3: \ 12835f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_PREPARE_SHORT_15: \ 12845f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP_CONVERT_AUX(opcode,cc_dep1,3); \ 12855f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 12865f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_EVEN_4: \ 12875f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_EVEN_8: \ 12885f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP_CONVERT_AUX(opcode,cc_dep1,4); \ 12895f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 12905f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_ZERO_5: \ 12915f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_ZERO_9: \ 12925f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP_CONVERT_AUX(opcode,cc_dep1,5); \ 12935f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 12945f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_POSINF_6: \ 12955f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_POSINF_10: \ 12965f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP_CONVERT_AUX(opcode,cc_dep1,6); \ 12975f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 12985f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEGINF_7: \ 12995f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEGINF_11: \ 13005f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP_CONVERT_AUX(opcode,cc_dep1,7); \ 13015f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 13025f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_TIE_TOWARD_0: \ 13035f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP_CONVERT_AUX(opcode,cc_dep1,13); \ 13045f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 13055f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_AWAY_0: \ 13065f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP_CONVERT_AUX(opcode,cc_dep1,14); \ 13075f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 13085f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian default: \ 13095f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian vpanic("unexpected dfp rounding mode"); \ 13105f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian } \ 13115f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc; \ 13125f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian }) 13135f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian 13145f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian#define S390_CC_FOR_DFP_UCONVERT_AUX(opcode,cc_dep1,rounding_mode) \ 13155f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian ({ \ 13165f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian __asm__ volatile ( \ 13175f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian opcode ",0,%[op]," #rounding_mode ",0\n\t" \ 13185f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian "ipm %[psw]\n\t" : [psw] "=d"(psw) \ 13195f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian : [op] "f"(cc_dep1) \ 13205f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian : "cc", "r0"); \ 13215f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian psw >> 28; /* cc */ \ 13225f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian }) 13235f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian 13245f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian#define S390_CC_FOR_DFP_UCONVERT(opcode,cc_dep1,cc_dep2) \ 13255f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian ({ \ 13265f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian UInt cc; \ 13275f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian switch (decode_dfp_rounding_mode(cc_dep2)) { \ 13285f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1: \ 13295f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12: \ 13305f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP_UCONVERT_AUX(opcode,cc_dep1,1); \ 13315f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 13325f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_PREPARE_SHORT_3: \ 13335f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_PREPARE_SHORT_15: \ 13345f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP_UCONVERT_AUX(opcode,cc_dep1,3); \ 13355f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 13365f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_EVEN_4: \ 13375f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_EVEN_8: \ 13385f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP_UCONVERT_AUX(opcode,cc_dep1,4); \ 13395f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 13405f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_ZERO_5: \ 13415f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_ZERO_9: \ 13425f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP_UCONVERT_AUX(opcode,cc_dep1,5); \ 13435f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 13445f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_POSINF_6: \ 13455f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_POSINF_10: \ 13465f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP_UCONVERT_AUX(opcode,cc_dep1,6); \ 13475f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 13485f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEGINF_7: \ 13495f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEGINF_11: \ 13505f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP_UCONVERT_AUX(opcode,cc_dep1,7); \ 13515f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 13525f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_TIE_TOWARD_0: \ 13535f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP_UCONVERT_AUX(opcode,cc_dep1,13); \ 13545f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 13555f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_AWAY_0: \ 13565f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP_UCONVERT_AUX(opcode,cc_dep1,14); \ 13575f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 13585f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian default: \ 13595f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian vpanic("unexpected dfp rounding mode"); \ 13605f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian } \ 13615f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc; \ 13625f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian }) 13635f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian 13645f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian#define S390_CC_FOR_DFP128_CONVERT_AUX(opcode,hi,lo,rounding_mode) \ 13655f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian ({ \ 13665f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian __asm__ volatile ( \ 13675f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian "ldr 4,%[high]\n\t" \ 13685f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian "ldr 6,%[low]\n\t" \ 13695f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian opcode ",0,4," #rounding_mode ",0\n\t" \ 13705f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian "ipm %[psw]\n\t" : [psw] "=d"(psw) \ 13715f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian : [high] "f"(hi), [low] "f"(lo) \ 13725f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian : "cc", "r0", "f4", "f6"); \ 13735f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian psw >> 28; /* cc */ \ 13745f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian }) 13755f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian 13765f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian#define S390_CC_FOR_DFP128_CONVERT(opcode,cc_dep1,cc_dep2,cc_ndep) \ 13775f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian ({ \ 13785f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian UInt cc; \ 13795f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian /* Recover the original DEP2 value. See comment near \ 13805f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian s390_cc_thunk_put3 for rationale. */ \ 13815f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc_dep2 = cc_dep2 ^ cc_ndep; \ 13825f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian switch (decode_dfp_rounding_mode(cc_ndep)) { \ 13835f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1: \ 13845f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12: \ 13855f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP128_CONVERT_AUX(opcode,cc_dep1,cc_dep2,1); \ 13865f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 13875f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_PREPARE_SHORT_3: \ 13885f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_PREPARE_SHORT_15: \ 13895f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP128_CONVERT_AUX(opcode,cc_dep1,cc_dep2,3); \ 13905f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 13915f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_EVEN_4: \ 13925f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_EVEN_8: \ 13935f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP128_CONVERT_AUX(opcode,cc_dep1,cc_dep2,4); \ 13945f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 13955f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_ZERO_5: \ 13965f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_ZERO_9: \ 13975f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP128_CONVERT_AUX(opcode,cc_dep1,cc_dep2,5); \ 13985f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 13995f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_POSINF_6: \ 14005f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_POSINF_10: \ 14015f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP128_CONVERT_AUX(opcode,cc_dep1,cc_dep2,6); \ 14025f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 14035f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEGINF_7: \ 14045f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEGINF_11: \ 14055f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP128_CONVERT_AUX(opcode,cc_dep1,cc_dep2,7); \ 14065f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 14075f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_TIE_TOWARD_0: \ 14085f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP128_CONVERT_AUX(opcode,cc_dep1,cc_dep2,13); \ 14095f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 14105f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_AWAY_0: \ 14115f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP128_CONVERT_AUX(opcode,cc_dep1,cc_dep2,14); \ 14125f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 14135f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian default: \ 14145f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian vpanic("unexpected dfp rounding mode"); \ 14155f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian } \ 14165f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc; \ 14175f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian }) 14185f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian 14195f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian#define S390_CC_FOR_DFP128_UCONVERT_AUX(opcode,hi,lo,rounding_mode) \ 14205f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian ({ \ 14215f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian __asm__ volatile ( \ 14225f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian "ldr 4,%[high]\n\t" \ 14235f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian "ldr 6,%[low]\n\t" \ 14245f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian opcode ",0,4," #rounding_mode ",0\n\t" \ 14255f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian "ipm %[psw]\n\t" : [psw] "=d"(psw) \ 14265f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian : [high] "f"(hi), [low] "f"(lo) \ 14275f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian : "cc", "r0", "f4", "f6"); \ 14285f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian psw >> 28; /* cc */ \ 14295f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian }) 14305f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian 14315f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian#define S390_CC_FOR_DFP128_UCONVERT(opcode,cc_dep1,cc_dep2,cc_ndep) \ 14325f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian ({ \ 14335f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian UInt cc; \ 14345f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian /* Recover the original DEP2 value. See comment near \ 14355f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian s390_cc_thunk_put3 for rationale. */ \ 14365f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc_dep2 = cc_dep2 ^ cc_ndep; \ 14375f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian switch (decode_dfp_rounding_mode(cc_ndep)) { \ 14385f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1: \ 14395f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12: \ 14405f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP128_UCONVERT_AUX(opcode,cc_dep1,cc_dep2,1); \ 14415f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 14425f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_PREPARE_SHORT_3: \ 14435f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_PREPARE_SHORT_15: \ 14445f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP128_UCONVERT_AUX(opcode,cc_dep1,cc_dep2,3); \ 14455f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 14465f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_EVEN_4: \ 14475f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_EVEN_8: \ 14485f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP128_UCONVERT_AUX(opcode,cc_dep1,cc_dep2,4); \ 14495f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 14505f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_ZERO_5: \ 14515f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_ZERO_9: \ 14525f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP128_UCONVERT_AUX(opcode,cc_dep1,cc_dep2,5); \ 14535f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 14545f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_POSINF_6: \ 14555f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_POSINF_10: \ 14565f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP128_UCONVERT_AUX(opcode,cc_dep1,cc_dep2,6); \ 14575f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 14585f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEGINF_7: \ 14595f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEGINF_11: \ 14605f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP128_UCONVERT_AUX(opcode,cc_dep1,cc_dep2,7); \ 14615f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 14625f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_TIE_TOWARD_0: \ 14635f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP128_UCONVERT_AUX(opcode,cc_dep1,cc_dep2,13); \ 14645f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 14655f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_AWAY_0: \ 14665f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP128_UCONVERT_AUX(opcode,cc_dep1,cc_dep2,14); \ 14675f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 14685f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian default: \ 14695f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian vpanic("unexpected dfp rounding mode"); \ 14705f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian } \ 14715f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc; \ 14725f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian }) 14735f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian 14742019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 14752019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/* Return the value of the condition code from the supplied thunk parameters. 14762019a976f07ff418dde2dfc7cc74667ef66d7764sewardj This is not the value of the PSW. It is the value of the 2 CC bits within 14772019a976f07ff418dde2dfc7cc74667ef66d7764sewardj the PSW. The returned value is thusly in the interval [0:3]. */ 14782019a976f07ff418dde2dfc7cc74667ef66d7764sewardjUInt 14792019a976f07ff418dde2dfc7cc74667ef66d7764sewardjs390_calculate_cc(ULong cc_op, ULong cc_dep1, ULong cc_dep2, ULong cc_ndep) 14802019a976f07ff418dde2dfc7cc74667ef66d7764sewardj{ 14812019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#if defined(VGA_s390x) 14822019a976f07ff418dde2dfc7cc74667ef66d7764sewardj UInt psw; 14832019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 14842019a976f07ff418dde2dfc7cc74667ef66d7764sewardj switch (cc_op) { 14852019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 14862019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_BITWISE: 14872019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_BINARY("ogr", cc_dep1, (ULong)0); 14882019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 14892019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_SIGNED_COMPARE: 14902019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_BINARY("cgr", cc_dep1, cc_dep2); 14912019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 14922019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_UNSIGNED_COMPARE: 14932019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_BINARY("clgr", cc_dep1, cc_dep2); 14942019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 14952019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_SIGNED_ADD_64: 14962019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_BINARY("agr", cc_dep1, cc_dep2); 14972019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 14982019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_SIGNED_ADD_32: 14992019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_BINARY("ar", cc_dep1, cc_dep2); 15002019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15012019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_SIGNED_SUB_64: 15022019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_BINARY("sgr", cc_dep1, cc_dep2); 15032019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15042019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_SIGNED_SUB_32: 15052019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_BINARY("sr", cc_dep1, cc_dep2); 15062019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15072019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_UNSIGNED_ADD_64: 15082019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_BINARY("algr", cc_dep1, cc_dep2); 15092019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15102019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_UNSIGNED_ADD_32: 15112019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_BINARY("alr", cc_dep1, cc_dep2); 15122019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15132019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_UNSIGNED_ADDC_64: 15142019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_TERNARY_ADDC("alcgr", cc_dep1, cc_dep2, cc_ndep); 15152019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15162019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_UNSIGNED_ADDC_32: 15172019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_TERNARY_ADDC("alcr", cc_dep1, cc_dep2, cc_ndep); 15182019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15192019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_UNSIGNED_SUB_64: 15202019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_BINARY("slgr", cc_dep1, cc_dep2); 15212019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15222019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_UNSIGNED_SUB_32: 15232019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_BINARY("slr", cc_dep1, cc_dep2); 15242019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15252019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_UNSIGNED_SUBB_64: 15262019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_TERNARY_SUBB("slbgr", cc_dep1, cc_dep2, cc_ndep); 15272019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15282019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_UNSIGNED_SUBB_32: 15292019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_TERNARY_SUBB("slbr", cc_dep1, cc_dep2, cc_ndep); 15302019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15312019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_LOAD_AND_TEST: 15322019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Like signed comparison with 0 */ 15332019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_BINARY("cgr", cc_dep1, (Long)0); 15342019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15352019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_LOAD_POSITIVE_32: 15362019a976f07ff418dde2dfc7cc74667ef66d7764sewardj __asm__ volatile ( 15372019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "lpr %[result],%[op]\n\t" 1538ae88411aaa8e0b99032fb0bdb04eec21edc54d88florian "ipm %[psw]\n\t" : [psw] "=d"(psw), [result] "=d"(cc_dep1) 1539ae88411aaa8e0b99032fb0bdb04eec21edc54d88florian : [op] "d"(cc_dep1) 1540ae88411aaa8e0b99032fb0bdb04eec21edc54d88florian : "cc"); 15412019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return psw >> 28; /* cc */ 15422019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15432019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_LOAD_POSITIVE_64: 15442019a976f07ff418dde2dfc7cc74667ef66d7764sewardj __asm__ volatile ( 15452019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "lpgr %[result],%[op]\n\t" 1546ae88411aaa8e0b99032fb0bdb04eec21edc54d88florian "ipm %[psw]\n\t" : [psw] "=d"(psw), [result] "=d"(cc_dep1) 1547ae88411aaa8e0b99032fb0bdb04eec21edc54d88florian : [op] "d"(cc_dep1) 1548ae88411aaa8e0b99032fb0bdb04eec21edc54d88florian : "cc"); 15492019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return psw >> 28; /* cc */ 15502019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15512019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_TEST_UNDER_MASK_8: { 15522019a976f07ff418dde2dfc7cc74667ef66d7764sewardj UChar value = cc_dep1; 15532019a976f07ff418dde2dfc7cc74667ef66d7764sewardj UChar mask = cc_dep2; 15542019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15552019a976f07ff418dde2dfc7cc74667ef66d7764sewardj __asm__ volatile ( 15562019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "bras %%r2,1f\n\t" /* %r2 = address of next insn */ 15572019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "tm %[value],0\n\t" /* this is skipped, then EXecuted */ 15582019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "1: ex %[mask],0(%%r2)\n\t" /* EXecute TM after modifying mask */ 15592019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ipm %[psw]\n\t" : [psw] "=d"(psw) 15602019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : [value] "m"(value), [mask] "a"(mask) 15612019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : "r2", "cc"); 15622019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return psw >> 28; /* cc */ 15632019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 15642019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15652019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_TEST_UNDER_MASK_16: { 15662019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Create a TMLL insn with the mask as given by cc_dep2 */ 15672019a976f07ff418dde2dfc7cc74667ef66d7764sewardj UInt insn = (0xA701 << 16) | cc_dep2; 15682019a976f07ff418dde2dfc7cc74667ef66d7764sewardj UInt value = cc_dep1; 15692019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15702019a976f07ff418dde2dfc7cc74667ef66d7764sewardj __asm__ volatile ( 15712019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "lr 1,%[value]\n\t" 15722019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "lhi 2,0x10\n\t" 15732019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ex 2,%[insn]\n\t" 15742019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ipm %[psw]\n\t" : [psw] "=d"(psw) 15752019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : [value] "d"(value), [insn] "m"(insn) 15762019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : "r1", "r2", "cc"); 15772019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return psw >> 28; /* cc */ 15782019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 15792019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15802019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_SHIFT_LEFT_32: 15812019a976f07ff418dde2dfc7cc74667ef66d7764sewardj __asm__ volatile ( 15822019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "sla %[op],0(%[amount])\n\t" 15832019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ipm %[psw]\n\t" : [psw] "=d"(psw), [op] "+d"(cc_dep1) 15842019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : [amount] "a"(cc_dep2) 15852019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : "cc"); 15862019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return psw >> 28; /* cc */ 15872019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15882019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_SHIFT_LEFT_64: { 15892019a976f07ff418dde2dfc7cc74667ef66d7764sewardj Int high = (Int)(cc_dep1 >> 32); 15902019a976f07ff418dde2dfc7cc74667ef66d7764sewardj Int low = (Int)(cc_dep1 & 0xFFFFFFFF); 15912019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15922019a976f07ff418dde2dfc7cc74667ef66d7764sewardj __asm__ volatile ( 15932019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "lr 2,%[high]\n\t" 15942019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "lr 3,%[low]\n\t" 15952019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "slda 2,0(%[amount])\n\t" 1596ae88411aaa8e0b99032fb0bdb04eec21edc54d88florian "ipm %[psw]\n\t" : [psw] "=d"(psw), [high] "+d"(high), 1597ae88411aaa8e0b99032fb0bdb04eec21edc54d88florian [low] "+d"(low) 15982019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : [amount] "a"(cc_dep2) 15992019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : "cc", "r2", "r3"); 16002019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return psw >> 28; /* cc */ 16012019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 16022019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 16032019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_INSERT_CHAR_MASK_32: { 16042019a976f07ff418dde2dfc7cc74667ef66d7764sewardj Int inserted = 0; 16052019a976f07ff418dde2dfc7cc74667ef66d7764sewardj Int msb = 0; 16062019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 16072019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cc_dep2 & 1) { 16082019a976f07ff418dde2dfc7cc74667ef66d7764sewardj inserted |= cc_dep1 & 0xff; 16092019a976f07ff418dde2dfc7cc74667ef66d7764sewardj msb = 0x80; 16102019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 16112019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cc_dep2 & 2) { 16122019a976f07ff418dde2dfc7cc74667ef66d7764sewardj inserted |= cc_dep1 & 0xff00; 16132019a976f07ff418dde2dfc7cc74667ef66d7764sewardj msb = 0x8000; 16142019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 16152019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cc_dep2 & 4) { 16162019a976f07ff418dde2dfc7cc74667ef66d7764sewardj inserted |= cc_dep1 & 0xff0000; 16172019a976f07ff418dde2dfc7cc74667ef66d7764sewardj msb = 0x800000; 16182019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 16192019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cc_dep2 & 8) { 16202019a976f07ff418dde2dfc7cc74667ef66d7764sewardj inserted |= cc_dep1 & 0xff000000; 16212019a976f07ff418dde2dfc7cc74667ef66d7764sewardj msb = 0x80000000; 16222019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 16232019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 16242019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (inserted & msb) // MSB is 1 16252019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return 1; 16262019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (inserted > 0) 16272019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return 2; 16282019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return 0; 16292019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 16302019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 16312019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_BFP_RESULT_32: 16322019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_BFP_RESULT("ltebr", cc_dep1); 16332019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 16342019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_BFP_RESULT_64: 16352019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_BFP_RESULT("ltdbr", cc_dep1); 16362019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 16372019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_BFP_RESULT_128: 16382019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_BFP128_RESULT(cc_dep1, cc_dep2); 16392019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 16402019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_BFP_32_TO_INT_32: 164119e0077d31fe17496eeb76cd008507d1a8f75908florian return S390_CC_FOR_BFP_CONVERT("cfebr", cc_dep1, cc_dep2); 16422019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 16432019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_BFP_64_TO_INT_32: 164419e0077d31fe17496eeb76cd008507d1a8f75908florian return S390_CC_FOR_BFP_CONVERT("cfdbr", cc_dep1, cc_dep2); 16452019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 16462019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_BFP_128_TO_INT_32: 164719e0077d31fe17496eeb76cd008507d1a8f75908florian return S390_CC_FOR_BFP128_CONVERT("cfxbr", cc_dep1, cc_dep2, cc_ndep); 16482019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 16492019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_BFP_32_TO_INT_64: 165019e0077d31fe17496eeb76cd008507d1a8f75908florian return S390_CC_FOR_BFP_CONVERT("cgebr", cc_dep1, cc_dep2); 16512019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 16522019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_BFP_64_TO_INT_64: 165319e0077d31fe17496eeb76cd008507d1a8f75908florian return S390_CC_FOR_BFP_CONVERT("cgdbr", cc_dep1, cc_dep2); 16542019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 16552019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_BFP_128_TO_INT_64: 165619e0077d31fe17496eeb76cd008507d1a8f75908florian return S390_CC_FOR_BFP128_CONVERT("cgxbr", cc_dep1, cc_dep2, cc_ndep); 16572019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 16582019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_BFP_TDC_32: 16592019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_BFP_TDC("tceb", cc_dep1, cc_dep2); 16602019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 16612019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_BFP_TDC_64: 16622019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_BFP_TDC("tcdb", cc_dep1, cc_dep2); 16632019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 16642019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_BFP_TDC_128: 16652019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_BFP128_TDC(cc_dep1, cc_dep2, cc_ndep); 16662019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 16672019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_SET: 16682019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return cc_dep1; 16692019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 16701c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian case S390_CC_OP_BFP_32_TO_UINT_32: 167119e0077d31fe17496eeb76cd008507d1a8f75908florian return S390_CC_FOR_BFP_UCONVERT(".insn rrf,0xb39c0000", cc_dep1, cc_dep2); 16721c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian 16731c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian case S390_CC_OP_BFP_64_TO_UINT_32: 167419e0077d31fe17496eeb76cd008507d1a8f75908florian return S390_CC_FOR_BFP_UCONVERT(".insn rrf,0xb39d0000", cc_dep1, cc_dep2); 16751c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian 16761c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian case S390_CC_OP_BFP_128_TO_UINT_32: 167719e0077d31fe17496eeb76cd008507d1a8f75908florian return S390_CC_FOR_BFP128_UCONVERT(".insn rrf,0xb39e0000", cc_dep1, 167819e0077d31fe17496eeb76cd008507d1a8f75908florian cc_dep2, cc_ndep); 16791c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian 16801c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian case S390_CC_OP_BFP_32_TO_UINT_64: 168119e0077d31fe17496eeb76cd008507d1a8f75908florian return S390_CC_FOR_BFP_UCONVERT(".insn rrf,0xb3ac0000", cc_dep1, cc_dep2); 16821c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian 16831c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian case S390_CC_OP_BFP_64_TO_UINT_64: 168419e0077d31fe17496eeb76cd008507d1a8f75908florian return S390_CC_FOR_BFP_UCONVERT(".insn rrf,0xb3ad0000", cc_dep1, cc_dep2); 16851c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian 16861c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian case S390_CC_OP_BFP_128_TO_UINT_64: 168719e0077d31fe17496eeb76cd008507d1a8f75908florian return S390_CC_FOR_BFP128_UCONVERT(".insn rrf,0xb3ae0000", cc_dep1, 168819e0077d31fe17496eeb76cd008507d1a8f75908florian cc_dep2, cc_ndep); 16891c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian 16901239020c948a6e20faaa8d0fa5dea44302e18f8aflorian case S390_CC_OP_DFP_RESULT_64: 16911239020c948a6e20faaa8d0fa5dea44302e18f8aflorian return S390_CC_FOR_DFP_RESULT(cc_dep1); 16921c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian 1693e38f641461120ea338069a3f45820168959968abflorian case S390_CC_OP_DFP_RESULT_128: 1694e38f641461120ea338069a3f45820168959968abflorian return S390_CC_FOR_DFP128_RESULT(cc_dep1, cc_dep2); 1695e38f641461120ea338069a3f45820168959968abflorian 1696ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian case S390_CC_OP_DFP_TDC_32: /* TDCET */ 1697ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian return S390_CC_FOR_DFP_TD(".insn rxe, 0xed0000000050", cc_dep1, cc_dep2); 1698ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian 1699ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian case S390_CC_OP_DFP_TDC_64: /* TDCDT */ 1700ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian return S390_CC_FOR_DFP_TD(".insn rxe, 0xed0000000054", cc_dep1, cc_dep2); 1701ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian 1702ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian case S390_CC_OP_DFP_TDC_128: /* TDCXT */ 1703ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian return S390_CC_FOR_DFP128_TD(".insn rxe, 0xed0000000058", cc_dep1, 1704ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian cc_dep2, cc_ndep); 1705ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian 1706ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian case S390_CC_OP_DFP_TDG_32: /* TDGET */ 1707ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian return S390_CC_FOR_DFP_TD(".insn rxe, 0xed0000000051", cc_dep1, cc_dep2); 1708ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian 1709ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian case S390_CC_OP_DFP_TDG_64: /* TDGDT */ 1710ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian return S390_CC_FOR_DFP_TD(".insn rxe, 0xed0000000055", cc_dep1, cc_dep2); 1711ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian 1712ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian case S390_CC_OP_DFP_TDG_128: /* TDGXT */ 1713ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian return S390_CC_FOR_DFP128_TD(".insn rxe, 0xed0000000059", cc_dep1, 1714ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian cc_dep2, cc_ndep); 1715ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian 17165f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_CC_OP_DFP_64_TO_INT_32: /* CFDTR */ 17175f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian return S390_CC_FOR_DFP_CONVERT(".insn rrf,0xb9410000", cc_dep1, cc_dep2); 17185f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian 17195f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_CC_OP_DFP_128_TO_INT_32: /* CFXTR */ 17205f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian return S390_CC_FOR_DFP128_CONVERT(".insn rrf,0xb9490000", cc_dep1, 17215f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc_dep2, cc_ndep); 17225f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian 1723a887acd341cb9b90b1dd6d3fdfa4a429f5ddd583florian case S390_CC_OP_DFP_64_TO_INT_64: /* CGDTR */ 1724a887acd341cb9b90b1dd6d3fdfa4a429f5ddd583florian return S390_CC_FOR_DFP_CONVERT(".insn rrf,0xb3e10000", cc_dep1, cc_dep2); 1725a887acd341cb9b90b1dd6d3fdfa4a429f5ddd583florian 1726a887acd341cb9b90b1dd6d3fdfa4a429f5ddd583florian case S390_CC_OP_DFP_128_TO_INT_64: /* CGXTR */ 1727a887acd341cb9b90b1dd6d3fdfa4a429f5ddd583florian return S390_CC_FOR_DFP128_CONVERT(".insn rrf,0xb3e90000", cc_dep1, 1728a887acd341cb9b90b1dd6d3fdfa4a429f5ddd583florian cc_dep2, cc_ndep); 1729a887acd341cb9b90b1dd6d3fdfa4a429f5ddd583florian 17305f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_CC_OP_DFP_64_TO_UINT_32: /* CLFDTR */ 17315f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian return S390_CC_FOR_DFP_UCONVERT(".insn rrf,0xb9430000", cc_dep1, cc_dep2); 17325f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian 17335f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_CC_OP_DFP_128_TO_UINT_32: /* CLFXTR */ 17345f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian return S390_CC_FOR_DFP128_UCONVERT(".insn rrf,0xb94b0000", cc_dep1, 17355f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc_dep2, cc_ndep); 17365f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian 17375f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_CC_OP_DFP_64_TO_UINT_64: /* CLGDTR */ 17385f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian return S390_CC_FOR_DFP_UCONVERT(".insn rrf,0xb9420000", cc_dep1, cc_dep2); 17395f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian 17405f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_CC_OP_DFP_128_TO_UINT_64: /* CLGXTR */ 17415f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian return S390_CC_FOR_DFP128_UCONVERT(".insn rrf,0xb94a0000", cc_dep1, 17425f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc_dep2, cc_ndep); 17435f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian 17447ab421d8483f8462f2bf5ebdd1ef5d72658dd572florian case S390_CC_OP_PFPO_32: { 17457ab421d8483f8462f2bf5ebdd1ef5d72658dd572florian __asm__ volatile( 17467ab421d8483f8462f2bf5ebdd1ef5d72658dd572florian "ler 4, %[cc_dep1]\n\t" /* 32 bit FR move */ 17477ab421d8483f8462f2bf5ebdd1ef5d72658dd572florian "lr 0, %[cc_dep2]\n\t" /* 32 bit GR move */ 17487ab421d8483f8462f2bf5ebdd1ef5d72658dd572florian ".short 0x010a\n\t" /* PFPO */ 17497ab421d8483f8462f2bf5ebdd1ef5d72658dd572florian "ipm %[psw]\n\t" : [psw] "=d"(psw) 17507ab421d8483f8462f2bf5ebdd1ef5d72658dd572florian : [cc_dep1] "f"(cc_dep1), 17517ab421d8483f8462f2bf5ebdd1ef5d72658dd572florian [cc_dep2] "d"(cc_dep2) 17527ab421d8483f8462f2bf5ebdd1ef5d72658dd572florian : "r0", "r1", "f4"); 17537ab421d8483f8462f2bf5ebdd1ef5d72658dd572florian return psw >> 28; /* cc */ 17547ab421d8483f8462f2bf5ebdd1ef5d72658dd572florian } 17557ab421d8483f8462f2bf5ebdd1ef5d72658dd572florian 175678d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian case S390_CC_OP_PFPO_64: { 175778d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian __asm__ volatile( 175878d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian "ldr 4, %[cc_dep1]\n\t" 175978d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian "lr 0, %[cc_dep2]\n\t" /* 32 bit register move */ 176078d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian ".short 0x010a\n\t" /* PFPO */ 176178d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian "ipm %[psw]\n\t" : [psw] "=d"(psw) 1762c589228fe86255c87fdc9ad78d5d9c60e4c9e61eflorian : [cc_dep1] "f"(cc_dep1), 1763c589228fe86255c87fdc9ad78d5d9c60e4c9e61eflorian [cc_dep2] "d"(cc_dep2) 176478d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian : "r0", "r1", "f4"); 176578d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian return psw >> 28; /* cc */ 176678d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian } 176778d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian 176878d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian case S390_CC_OP_PFPO_128: { 176978d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian __asm__ volatile( 177078d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian "ldr 4,%[cc_dep1]\n\t" 177178d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian "ldr 6,%[cc_dep2]\n\t" 177278d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian "lr 0,%[cc_ndep]\n\t" /* 32 bit register move */ 177378d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian ".short 0x010a\n\t" /* PFPO */ 177478d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian "ipm %[psw]\n\t" : [psw] "=d"(psw) 177578d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian : [cc_dep1] "f"(cc_dep1), 177678d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian [cc_dep2] "f"(cc_dep2), 177778d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian [cc_ndep] "d"(cc_ndep) 177878d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian : "r0", "r1", "f0", "f2", "f4", "f6"); 177978d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian return psw >> 28; /* cc */ 178078d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian } 178178d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian 17822019a976f07ff418dde2dfc7cc74667ef66d7764sewardj default: 17832019a976f07ff418dde2dfc7cc74667ef66d7764sewardj break; 17842019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 17852019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#endif 17862019a976f07ff418dde2dfc7cc74667ef66d7764sewardj vpanic("s390_calculate_cc"); 17872019a976f07ff418dde2dfc7cc74667ef66d7764sewardj} 17882019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 17892019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 17902019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/* Note that this does *not* return a Boolean value. The result needs to be 17912019a976f07ff418dde2dfc7cc74667ef66d7764sewardj explicitly tested against zero. */ 17922019a976f07ff418dde2dfc7cc74667ef66d7764sewardjUInt 17932019a976f07ff418dde2dfc7cc74667ef66d7764sewardjs390_calculate_cond(ULong mask, ULong op, ULong dep1, ULong dep2, ULong ndep) 17942019a976f07ff418dde2dfc7cc74667ef66d7764sewardj{ 17952019a976f07ff418dde2dfc7cc74667ef66d7764sewardj UInt cc = s390_calculate_cc(op, dep1, dep2, ndep); 17962019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 17972019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return ((mask << cc) & 0x8); 17982019a976f07ff418dde2dfc7cc74667ef66d7764sewardj} 17992019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18002019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*------------------------------------------------------------*/ 18012019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*--- spechelper for performance ---*/ 18022019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*------------------------------------------------------------*/ 18032019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18042019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18052019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/* Convenience macros */ 18062019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#define unop(op,a1) IRExpr_Unop((op),(a1)) 18072019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#define binop(op,a1,a2) IRExpr_Binop((op),(a1),(a2)) 18082019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#define mkU64(v) IRExpr_Const(IRConst_U64(v)) 18092019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#define mkU32(v) IRExpr_Const(IRConst_U32(v)) 18102019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#define mkU8(v) IRExpr_Const(IRConst_U8(v)) 18112019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18122019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18132019a976f07ff418dde2dfc7cc74667ef66d7764sewardjstatic inline Bool 181449adf8664fa8e67c95397022d21ea1b547e2186bflorianisC64(const IRExpr *expr) 18152019a976f07ff418dde2dfc7cc74667ef66d7764sewardj{ 18162019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return expr->tag == Iex_Const && expr->Iex.Const.con->tag == Ico_U64; 18172019a976f07ff418dde2dfc7cc74667ef66d7764sewardj} 18182019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18192019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18202019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/* The returned expression is NULL if no specialization was found. In that 18212019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case the helper function will be called. Otherwise, the expression has 18222019a976f07ff418dde2dfc7cc74667ef66d7764sewardj type Ity_I32 and a Boolean value. */ 18232019a976f07ff418dde2dfc7cc74667ef66d7764sewardjIRExpr * 18241ff4756e1731485e6bf3cd96717cd8398daec1f2florianguest_s390x_spechelper(const HChar *function_name, IRExpr **args, 18252019a976f07ff418dde2dfc7cc74667ef66d7764sewardj IRStmt **precedingStmts, Int n_precedingStmts) 18262019a976f07ff418dde2dfc7cc74667ef66d7764sewardj{ 18272019a976f07ff418dde2dfc7cc74667ef66d7764sewardj UInt i, arity = 0; 18282019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18292019a976f07ff418dde2dfc7cc74667ef66d7764sewardj for (i = 0; args[i]; i++) 18302019a976f07ff418dde2dfc7cc74667ef66d7764sewardj arity++; 18312019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18322019a976f07ff418dde2dfc7cc74667ef66d7764sewardj# if 0 18332019a976f07ff418dde2dfc7cc74667ef66d7764sewardj vex_printf("spec request:\n"); 18342019a976f07ff418dde2dfc7cc74667ef66d7764sewardj vex_printf(" %s ", function_name); 18352019a976f07ff418dde2dfc7cc74667ef66d7764sewardj for (i = 0; i < arity; i++) { 18362019a976f07ff418dde2dfc7cc74667ef66d7764sewardj vex_printf(" "); 18372019a976f07ff418dde2dfc7cc74667ef66d7764sewardj ppIRExpr(args[i]); 18382019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 18392019a976f07ff418dde2dfc7cc74667ef66d7764sewardj vex_printf("\n"); 18402019a976f07ff418dde2dfc7cc74667ef66d7764sewardj# endif 18412019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18422019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* --------- Specialising "s390_calculate_cond" --------- */ 18432019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18442019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (vex_streq(function_name, "s390_calculate_cond")) { 18452019a976f07ff418dde2dfc7cc74667ef66d7764sewardj IRExpr *cond_expr, *cc_op_expr, *cc_dep1, *cc_dep2; 18462019a976f07ff418dde2dfc7cc74667ef66d7764sewardj ULong cond, cc_op; 18472019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18482019a976f07ff418dde2dfc7cc74667ef66d7764sewardj vassert(arity == 5); 18492019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18502019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cond_expr = args[0]; 18512019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc_op_expr = args[1]; 18522019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18532019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* The necessary requirement for all optimizations here is that the 18542019a976f07ff418dde2dfc7cc74667ef66d7764sewardj condition and the cc_op are constant. So check that upfront. */ 18552019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (! isC64(cond_expr)) return NULL; 18562019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (! isC64(cc_op_expr)) return NULL; 18572019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18582019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cond = cond_expr->Iex.Const.con->Ico.U64; 18592019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc_op = cc_op_expr->Iex.Const.con->Ico.U64; 18602019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18612019a976f07ff418dde2dfc7cc74667ef66d7764sewardj vassert(cond <= 15); 18622019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18632019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* 18642019a976f07ff418dde2dfc7cc74667ef66d7764sewardj +------+---+---+---+---+ 18652019a976f07ff418dde2dfc7cc74667ef66d7764sewardj | cc | 0 | 1 | 2 | 3 | 18662019a976f07ff418dde2dfc7cc74667ef66d7764sewardj | cond | 8 | 4 | 2 | 1 | 18672019a976f07ff418dde2dfc7cc74667ef66d7764sewardj +------+---+---+---+---+ 18682019a976f07ff418dde2dfc7cc74667ef66d7764sewardj */ 18692019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc_dep1 = args[2]; 18702019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc_dep2 = args[3]; 18712019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18722019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* S390_CC_OP_SIGNED_COMPARE */ 18732019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cc_op == S390_CC_OP_SIGNED_COMPARE) { 18742019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* 18752019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 0 --> cc_dep1 == cc_dep2 (cond == 8) 18762019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 1 --> cc_dep1 < cc_dep2 (cond == 4) 18772019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 2 --> cc_dep1 > cc_dep2 (cond == 2) 18782019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18792019a976f07ff418dde2dfc7cc74667ef66d7764sewardj Because cc == 3 cannot occur the rightmost bit of cond is 18802019a976f07ff418dde2dfc7cc74667ef66d7764sewardj a don't care. 18812019a976f07ff418dde2dfc7cc74667ef66d7764sewardj */ 18822019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 || cond == 8 + 1) { 18832019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpEQ64, cc_dep1, cc_dep2)); 18842019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 18852019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 4 + 2 || cond == 4 + 2 + 1) { 18862019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpNE64, cc_dep1, cc_dep2)); 18872019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 18882019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 4 || cond == 4 + 1) { 18892019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpLT64S, cc_dep1, cc_dep2)); 18902019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 18912019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 + 4 || cond == 8 + 4 + 1) { 18922019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpLE64S, cc_dep1, cc_dep2)); 18932019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 18942019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* cc_dep1 > cc_dep2 ----> cc_dep2 < cc_dep1 */ 18952019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 2 || cond == 2 + 1) { 18962019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpLT64S, cc_dep2, cc_dep1)); 18972019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 18982019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 + 2 || cond == 8 + 2 + 1) { 18992019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpLE64S, cc_dep2, cc_dep1)); 19002019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19012019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 + 4 + 2 || cond == 8 + 4 + 2 + 1) { 19022019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return mkU32(1); 19032019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19042019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Remaining case */ 19052019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return mkU32(0); 19062019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19072019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 19082019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* S390_CC_OP_UNSIGNED_COMPARE */ 19092019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cc_op == S390_CC_OP_UNSIGNED_COMPARE) { 19102019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* 19112019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 0 --> cc_dep1 == cc_dep2 (cond == 8) 19122019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 1 --> cc_dep1 < cc_dep2 (cond == 4) 19132019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 2 --> cc_dep1 > cc_dep2 (cond == 2) 19142019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 19152019a976f07ff418dde2dfc7cc74667ef66d7764sewardj Because cc == 3 cannot occur the rightmost bit of cond is 19162019a976f07ff418dde2dfc7cc74667ef66d7764sewardj a don't care. 19172019a976f07ff418dde2dfc7cc74667ef66d7764sewardj */ 19182019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 || cond == 8 + 1) { 19192019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpEQ64, cc_dep1, cc_dep2)); 19202019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19212019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 4 + 2 || cond == 4 + 2 + 1) { 19222019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpNE64, cc_dep1, cc_dep2)); 19232019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19242019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 4 || cond == 4 + 1) { 19252019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpLT64U, cc_dep1, cc_dep2)); 19262019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19272019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 + 4 || cond == 8 + 4 + 1) { 19282019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpLE64U, cc_dep1, cc_dep2)); 19292019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19302019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* cc_dep1 > cc_dep2 ----> cc_dep2 < cc_dep1 */ 19312019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 2 || cond == 2 + 1) { 19322019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpLT64U, cc_dep2, cc_dep1)); 19332019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19342019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 + 2 || cond == 8 + 2 + 1) { 19352019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpLE64U, cc_dep2, cc_dep1)); 19362019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19372019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 + 4 + 2 || cond == 8 + 4 + 2 + 1) { 19382019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return mkU32(1); 19392019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19402019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Remaining case */ 19412019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return mkU32(0); 19422019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19432019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 19442019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* S390_CC_OP_LOAD_AND_TEST */ 19452019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cc_op == S390_CC_OP_LOAD_AND_TEST) { 19462019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* 19472019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 0 --> cc_dep1 == 0 (cond == 8) 19482019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 1 --> cc_dep1 < 0 (cond == 4) 19492019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 2 --> cc_dep1 > 0 (cond == 2) 19502019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 19512019a976f07ff418dde2dfc7cc74667ef66d7764sewardj Because cc == 3 cannot occur the rightmost bit of cond is 19522019a976f07ff418dde2dfc7cc74667ef66d7764sewardj a don't care. 19532019a976f07ff418dde2dfc7cc74667ef66d7764sewardj */ 19542019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 || cond == 8 + 1) { 19552019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpEQ64, cc_dep1, mkU64(0))); 19562019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19572019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 4 + 2 || cond == 4 + 2 + 1) { 19582019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpNE64, cc_dep1, mkU64(0))); 19592019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19602019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 4 || cond == 4 + 1) { 19612019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpLT64S, cc_dep1, mkU64(0))); 19622019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19632019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 + 4 || cond == 8 + 4 + 1) { 19642019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpLE64S, cc_dep1, mkU64(0))); 19652019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19662019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* cc_dep1 > 0 ----> 0 < cc_dep1 */ 19672019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 2 || cond == 2 + 1) { 19682019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpLT64S, mkU64(0), cc_dep1)); 19692019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19702019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 + 2 || cond == 8 + 2 + 1) { 197125e1cb271253c82bc8610820004116bad5e8d0a1florian /* Special case cc_dep >= 0. Only check the MSB to avoid bogus 197225e1cb271253c82bc8610820004116bad5e8d0a1florian memcheck complaints due to gcc magic. Fixes 308427 1973d7f19c077688845dcea5a037fe42ab5b1f7db717cborntra */ 197425e1cb271253c82bc8610820004116bad5e8d0a1florian return unop(Iop_64to32, binop(Iop_Xor64, 197525e1cb271253c82bc8610820004116bad5e8d0a1florian binop(Iop_Shr64, cc_dep1, mkU8(63)), 197625e1cb271253c82bc8610820004116bad5e8d0a1florian mkU64(1))); 19772019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19782019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 + 4 + 2 || cond == 8 + 4 + 2 + 1) { 19792019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return mkU32(1); 19802019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19812019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Remaining case */ 19822019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return mkU32(0); 19832019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19842019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 19852019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* S390_CC_OP_BITWISE */ 19862019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cc_op == S390_CC_OP_BITWISE) { 19872019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* 19882019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc_dep1 is the result of the boolean operation. 19892019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 19902019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 0 --> cc_dep1 == 0 (cond == 8) 19912019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 1 --> cc_dep1 != 0 (cond == 4) 19922019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 19932019a976f07ff418dde2dfc7cc74667ef66d7764sewardj Because cc == 2 and cc == 3 cannot occur the two rightmost bits of 19942019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cond are don't cares. Therefore: 19952019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 19962019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cond == 00xx -> always false 19972019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cond == 01xx -> not equal 19982019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cond == 10xx -> equal 19992019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cond == 11xx -> always true 20002019a976f07ff418dde2dfc7cc74667ef66d7764sewardj */ 20012019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if ((cond & (8 + 4)) == 8 + 4) { 20022019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return mkU32(1); 20032019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 20042019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond & 8) { 20052019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpEQ64, cc_dep1, mkU64(0))); 20062019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 20072019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond & 4) { 20082019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpNE64, cc_dep1, mkU64(0))); 20092019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 20102019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Remaining case */ 20112019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return mkU32(0); 20122019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 20132019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 20142019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* S390_CC_OP_INSERT_CHAR_MASK_32 20152019a976f07ff418dde2dfc7cc74667ef66d7764sewardj Since the mask comes from an immediate field in the opcode, we 20162019a976f07ff418dde2dfc7cc74667ef66d7764sewardj expect the mask to be a constant here. That simplifies matters. */ 20172019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cc_op == S390_CC_OP_INSERT_CHAR_MASK_32) { 20182019a976f07ff418dde2dfc7cc74667ef66d7764sewardj ULong mask; 20192019a976f07ff418dde2dfc7cc74667ef66d7764sewardj UInt imask = 0, shift = 0; 20202019a976f07ff418dde2dfc7cc74667ef66d7764sewardj IRExpr *word; 20212019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 20222019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (! isC64(cc_dep2)) goto missed; 20232019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 20242019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mask = cc_dep2->Iex.Const.con->Ico.U64; 20252019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 20262019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Extract the 32-bit value from the thunk */ 20272019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 20282019a976f07ff418dde2dfc7cc74667ef66d7764sewardj word = unop(Iop_64to32, cc_dep1); 20292019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 20302019a976f07ff418dde2dfc7cc74667ef66d7764sewardj switch (mask) { 20312019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case 0: shift = 0; imask = 0x00000000; break; 20322019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case 1: shift = 24; imask = 0x000000FF; break; 20332019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case 2: shift = 16; imask = 0x0000FF00; break; 20342019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case 3: shift = 16; imask = 0x0000FFFF; break; 20352019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case 4: shift = 8; imask = 0x00FF0000; break; 20362019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case 5: shift = 8; imask = 0x00FF00FF; break; 20372019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case 6: shift = 8; imask = 0x00FFFF00; break; 20382019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case 7: shift = 8; imask = 0x00FFFFFF; break; 20392019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case 8: shift = 0; imask = 0xFF000000; break; 20402019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case 9: shift = 0; imask = 0xFF0000FF; break; 20412019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case 10: shift = 0; imask = 0xFF00FF00; break; 20422019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case 11: shift = 0; imask = 0xFF00FFFF; break; 20432019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case 12: shift = 0; imask = 0xFFFF0000; break; 20442019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case 13: shift = 0; imask = 0xFFFF00FF; break; 20452019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case 14: shift = 0; imask = 0xFFFFFF00; break; 20462019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case 15: shift = 0; imask = 0xFFFFFFFF; break; 20472019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 20482019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 20492019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Select the bits that were inserted */ 20502019a976f07ff418dde2dfc7cc74667ef66d7764sewardj word = binop(Iop_And32, word, mkU32(imask)); 20512019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 20522019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* cc == 0 --> all inserted bits zero or mask == 0 (cond == 8) 20532019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 1 --> leftmost inserted bit is one (cond == 4) 20542019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 2 --> leftmost inserted bit is zero and not (cond == 2) 20552019a976f07ff418dde2dfc7cc74667ef66d7764sewardj all inserted bits are zero 20562019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 20572019a976f07ff418dde2dfc7cc74667ef66d7764sewardj Because cc == 0,1,2 the rightmost bit of the mask is a don't care */ 20582019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 || cond == 8 + 1) { 20592019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpEQ32, word, mkU32(0))); 20602019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 20612019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 4 + 2 || cond == 4 + 2 + 1) { 20622019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpNE32, word, mkU32(0))); 20632019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 20642019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 20652019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Sign extend */ 20662019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (shift != 0) { 20672019a976f07ff418dde2dfc7cc74667ef66d7764sewardj word = binop(Iop_Sar32, binop(Iop_Shl32, word, mkU8(shift)), 20682019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU8(shift)); 20692019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 20702019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 20712019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 4 || cond == 4 + 1) { /* word < 0 */ 20722019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpLT32S, word, mkU32(0))); 20732019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 20742019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 2 || cond == 2 + 1) { /* word > 0 */ 20752019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpLT32S, mkU32(0), word)); 20762019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 20772019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 + 4 || cond == 8 + 4 + 1) { 20782019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpLE32S, word, mkU32(0))); 20792019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 20802019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 + 2 || cond == 8 + 2 + 1) { 20812019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpLE32S, mkU32(0), word)); 20822019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 20832019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 + 4 + 2 || cond == 8 + 4 + 2 + 1) { 20842019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return mkU32(1); 20852019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 20862019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Remaining case */ 20872019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return mkU32(0); 20882019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 20892019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 20902019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* S390_CC_OP_TEST_UNDER_MASK_8 20912019a976f07ff418dde2dfc7cc74667ef66d7764sewardj Since the mask comes from an immediate field in the opcode, we 20922019a976f07ff418dde2dfc7cc74667ef66d7764sewardj expect the mask to be a constant here. That simplifies matters. */ 20932019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cc_op == S390_CC_OP_TEST_UNDER_MASK_8) { 20942019a976f07ff418dde2dfc7cc74667ef66d7764sewardj ULong mask16; 20952019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 20962019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (! isC64(cc_dep2)) goto missed; 20972019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 20982019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mask16 = cc_dep2->Iex.Const.con->Ico.U64; 20992019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 21002019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Get rid of the mask16 == 0 case first. Some of the simplifications 21012019a976f07ff418dde2dfc7cc74667ef66d7764sewardj below (e.g. for OVFL) only hold if mask16 == 0. */ 21022019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (mask16 == 0) { /* cc == 0 */ 21032019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond & 0x8) return mkU32(1); 21042019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return mkU32(0); 21052019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 21062019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 21072019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* cc == 2 is a don't care */ 21082019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 || cond == 8 + 2) { 21092019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpEQ64, 21102019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_And64, cc_dep1, cc_dep2), 21112019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(0))); 21122019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 21132019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 7 || cond == 7 - 2) { 21142019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpNE64, 21152019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_And64, cc_dep1, cc_dep2), 21162019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(0))); 21172019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 21182019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 1 || cond == 1 + 2) { 21192019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpEQ64, 21202019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_And64, cc_dep1, cc_dep2), 21212019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc_dep2)); 21222019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 21232019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 14 || cond == 14 - 2) { /* ! OVFL */ 21242019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpNE64, 21252019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_And64, cc_dep1, cc_dep2), 21262019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc_dep2)); 21272019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 21282019a976f07ff418dde2dfc7cc74667ef66d7764sewardj goto missed; 21292019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 21302019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 21312019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* S390_CC_OP_TEST_UNDER_MASK_16 21322019a976f07ff418dde2dfc7cc74667ef66d7764sewardj Since the mask comes from an immediate field in the opcode, we 21332019a976f07ff418dde2dfc7cc74667ef66d7764sewardj expect the mask to be a constant here. That simplifies matters. */ 21342019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cc_op == S390_CC_OP_TEST_UNDER_MASK_16) { 21352019a976f07ff418dde2dfc7cc74667ef66d7764sewardj ULong mask16; 21362019a976f07ff418dde2dfc7cc74667ef66d7764sewardj UInt msb; 21372019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 21382019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (! isC64(cc_dep2)) goto missed; 21392019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 21402019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mask16 = cc_dep2->Iex.Const.con->Ico.U64; 21412019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 21422019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Get rid of the mask16 == 0 case first. Some of the simplifications 21432019a976f07ff418dde2dfc7cc74667ef66d7764sewardj below (e.g. for OVFL) only hold if mask16 == 0. */ 21442019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (mask16 == 0) { /* cc == 0 */ 21452019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond & 0x8) return mkU32(1); 21462019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return mkU32(0); 21472019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 21482019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 21492019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8) { 21502019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpEQ64, 21512019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_And64, cc_dep1, cc_dep2), 21522019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(0))); 21532019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 21542019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 7) { 21552019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpNE64, 21562019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_And64, cc_dep1, cc_dep2), 21572019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(0))); 21582019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 21592019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 1) { 21602019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpEQ64, 21612019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_And64, cc_dep1, cc_dep2), 21622019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(mask16))); 21632019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 21642019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 14) { /* ! OVFL */ 21652019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpNE64, 21662019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_And64, cc_dep1, cc_dep2), 21672019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(mask16))); 21682019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 21692019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 21702019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Find MSB in mask */ 21712019a976f07ff418dde2dfc7cc74667ef66d7764sewardj msb = 0x8000; 21722019a976f07ff418dde2dfc7cc74667ef66d7764sewardj while (msb > mask16) 21732019a976f07ff418dde2dfc7cc74667ef66d7764sewardj msb >>= 1; 21742019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 21752019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 2) { /* cc == 2 */ 21762019a976f07ff418dde2dfc7cc74667ef66d7764sewardj IRExpr *c1, *c2; 21772019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 21782019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* (cc_dep & msb) != 0 && (cc_dep & mask16) != mask16 */ 21792019a976f07ff418dde2dfc7cc74667ef66d7764sewardj c1 = binop(Iop_CmpNE64, 21802019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_And64, cc_dep1, mkU64(msb)), mkU64(0)); 21812019a976f07ff418dde2dfc7cc74667ef66d7764sewardj c2 = binop(Iop_CmpNE64, 21822019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_And64, cc_dep1, cc_dep2), 21832019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(mask16)); 21842019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return binop(Iop_And32, unop(Iop_1Uto32, c1), 21852019a976f07ff418dde2dfc7cc74667ef66d7764sewardj unop(Iop_1Uto32, c2)); 21862019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 21872019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 21882019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 4) { /* cc == 1 */ 21892019a976f07ff418dde2dfc7cc74667ef66d7764sewardj IRExpr *c1, *c2; 21902019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 21912019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* (cc_dep & msb) == 0 && (cc_dep & mask16) != 0 */ 21922019a976f07ff418dde2dfc7cc74667ef66d7764sewardj c1 = binop(Iop_CmpEQ64, 21932019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_And64, cc_dep1, mkU64(msb)), mkU64(0)); 21942019a976f07ff418dde2dfc7cc74667ef66d7764sewardj c2 = binop(Iop_CmpNE64, 21952019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_And64, cc_dep1, cc_dep2), 21962019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(0)); 21972019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return binop(Iop_And32, unop(Iop_1Uto32, c1), 21982019a976f07ff418dde2dfc7cc74667ef66d7764sewardj unop(Iop_1Uto32, c2)); 21992019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 22002019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 22012019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 11) { /* cc == 0,2,3 */ 22022019a976f07ff418dde2dfc7cc74667ef66d7764sewardj IRExpr *c1, *c2; 22032019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 22042019a976f07ff418dde2dfc7cc74667ef66d7764sewardj c1 = binop(Iop_CmpNE64, 22052019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_And64, cc_dep1, mkU64(msb)), mkU64(0)); 22062019a976f07ff418dde2dfc7cc74667ef66d7764sewardj c2 = binop(Iop_CmpEQ64, 22072019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_And64, cc_dep1, cc_dep2), 22082019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(0)); 22092019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return binop(Iop_Or32, unop(Iop_1Uto32, c1), 22102019a976f07ff418dde2dfc7cc74667ef66d7764sewardj unop(Iop_1Uto32, c2)); 22112019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 22122019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 22132019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 3) { /* cc == 2 || cc == 3 */ 22142019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, 22152019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_CmpNE64, 22162019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_And64, cc_dep1, mkU64(msb)), 22172019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(0))); 22182019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 22192019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 12) { /* cc == 0 || cc == 1 */ 22202019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, 22212019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_CmpEQ64, 22222019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_And64, cc_dep1, mkU64(msb)), 22232019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(0))); 22242019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 22252019a976f07ff418dde2dfc7cc74667ef66d7764sewardj // vex_printf("TUM mask = 0x%llx\n", mask16); 22262019a976f07ff418dde2dfc7cc74667ef66d7764sewardj goto missed; 22272019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 22282019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 22292019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* S390_CC_OP_UNSIGNED_SUB_64/32 */ 22302019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cc_op == S390_CC_OP_UNSIGNED_SUB_64 || 22312019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc_op == S390_CC_OP_UNSIGNED_SUB_32) { 22322019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* 22332019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc_dep1, cc_dep2 are the zero extended left and right operands 22342019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 22352019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 1 --> result != 0, borrow (cond == 4) 22362019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 2 --> result == 0, no borrow (cond == 2) 22372019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 3 --> result != 0, no borrow (cond == 1) 22382019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 22392019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc = (cc_dep1 == cc_dep2) ? 2 22402019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : (cc_dep1 > cc_dep2) ? 3 : 1; 22412019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 22422019a976f07ff418dde2dfc7cc74667ef66d7764sewardj Because cc == 0 cannot occur the leftmost bit of cond is 22432019a976f07ff418dde2dfc7cc74667ef66d7764sewardj a don't care. 22442019a976f07ff418dde2dfc7cc74667ef66d7764sewardj */ 22452019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 1 || cond == 1 + 8) { /* cc == 3 op2 < op1 */ 22462019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpLT64U, cc_dep2, cc_dep1)); 22472019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 22482019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 2 || cond == 2 + 8) { /* cc == 2 */ 22492019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpEQ64, cc_dep1, cc_dep2)); 22502019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 22512019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 4 || cond == 4 + 8) { /* cc == 1 */ 22522019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpLT64U, cc_dep1, cc_dep2)); 22532019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 22542019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 3 || cond == 3 + 8) { /* cc == 2 || cc == 3 */ 22552019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpLE64U, cc_dep2, cc_dep1)); 22562019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 22572019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 6 || cond == 6 + 8) { /* cc == 2 || cc == 1 */ 22582019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpLE64U, cc_dep1, cc_dep2)); 22592019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 22602019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 22612019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 5 || cond == 5 + 8) { /* cc == 3 || cc == 1 */ 22622019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpNE64, cc_dep1, cc_dep2)); 22632019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 22642019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 7 || cond == 7 + 8) { 22652019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return mkU32(1); 22662019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 22672019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Remaining case */ 22682019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return mkU32(0); 22692019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 22702019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 22712019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* S390_CC_OP_UNSIGNED_ADD_64 */ 22722019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cc_op == S390_CC_OP_UNSIGNED_ADD_64) { 22732019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* 22742019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc_dep1, cc_dep2 are the zero extended left and right operands 22752019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 22762019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 0 --> result == 0, no carry (cond == 8) 22772019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 1 --> result != 0, no carry (cond == 4) 22782019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 2 --> result == 0, carry (cond == 2) 22792019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 3 --> result != 0, carry (cond == 1) 22802019a976f07ff418dde2dfc7cc74667ef66d7764sewardj */ 22812019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8) { /* cc == 0 */ 22822019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Both inputs are 0 */ 22832019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpEQ64, 22842019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_Or64, cc_dep1, cc_dep2), 22852019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(0))); 22862019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 22872019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 7) { /* cc == 1,2,3 */ 22882019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Not both inputs are 0 */ 22892019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpNE64, 22902019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_Or64, cc_dep1, cc_dep2), 22912019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(0))); 22922019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 22932019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 + 2) { /* cc == 0,2 -> result is zero */ 22942019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpEQ64, 22952019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_Add64, cc_dep1, cc_dep2), 22962019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(0))); 22972019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 22982019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 4 + 1) { /* cc == 1,3 -> result is not zero */ 22992019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpNE64, 23002019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_Add64, cc_dep1, cc_dep2), 23012019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(0))); 23022019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 23032019a976f07ff418dde2dfc7cc74667ef66d7764sewardj goto missed; 23042019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 23052019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 23062019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* S390_CC_OP_UNSIGNED_ADD_32 */ 23072019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cc_op == S390_CC_OP_UNSIGNED_ADD_32) { 23082019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* 23092019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc_dep1, cc_dep2 are the zero extended left and right operands 23102019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 23112019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 0 --> result == 0, no carry (cond == 8) 23122019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 1 --> result != 0, no carry (cond == 4) 23132019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 2 --> result == 0, carry (cond == 2) 23142019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 3 --> result != 0, carry (cond == 1) 23152019a976f07ff418dde2dfc7cc74667ef66d7764sewardj */ 23162019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8) { /* cc == 0 */ 23172019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Both inputs are 0 */ 23182019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpEQ64, 23192019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_Or64, cc_dep1, cc_dep2), 23202019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(0))); 23212019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 23222019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 7) { /* cc == 1,2,3 */ 23232019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Not both inputs are 0 */ 23242019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpNE64, 23252019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_Or64, cc_dep1, cc_dep2), 23262019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(0))); 23272019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 23282019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 + 2) { /* cc == 0,2 -> result is zero */ 23292019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpEQ32, 23302019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_Add32, 23312019a976f07ff418dde2dfc7cc74667ef66d7764sewardj unop(Iop_64to32, cc_dep1), 23322019a976f07ff418dde2dfc7cc74667ef66d7764sewardj unop(Iop_64to32, cc_dep2)), 23332019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU32(0))); 23342019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 23352019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 4 + 1) { /* cc == 1,3 -> result is not zero */ 23362019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpNE32, 23372019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_Add32, 23382019a976f07ff418dde2dfc7cc74667ef66d7764sewardj unop(Iop_64to32, cc_dep1), 23392019a976f07ff418dde2dfc7cc74667ef66d7764sewardj unop(Iop_64to32, cc_dep2)), 23402019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU32(0))); 23412019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 23422019a976f07ff418dde2dfc7cc74667ef66d7764sewardj goto missed; 23432019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 23442019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 23452019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* S390_CC_OP_SET */ 23462019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cc_op == S390_CC_OP_SET) { 23472019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* cc_dep1 is the condition code 23482019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 23492019a976f07ff418dde2dfc7cc74667ef66d7764sewardj Return 1, if ((cond << cc_dep1) & 0x8) != 0 */ 23502019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 23512019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, 23522019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_CmpNE64, 23532019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_And64, 23542019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_Shl64, cond_expr, 23552019a976f07ff418dde2dfc7cc74667ef66d7764sewardj unop(Iop_64to8, cc_dep1)), 23562019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(8)), 23572019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(0))); 23582019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 23592019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 2360af514c044bf90048e9bb916024198f9bc5dcb3f5florian goto missed; 23612019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 23622019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 2363af514c044bf90048e9bb916024198f9bc5dcb3f5florian /* --------- Specialising "s390_calculate_cond" --------- */ 2364af514c044bf90048e9bb916024198f9bc5dcb3f5florian 2365af514c044bf90048e9bb916024198f9bc5dcb3f5florian if (vex_streq(function_name, "s390_calculate_cc")) { 2366af514c044bf90048e9bb916024198f9bc5dcb3f5florian IRExpr *cc_op_expr, *cc_dep1; 2367af514c044bf90048e9bb916024198f9bc5dcb3f5florian ULong cc_op; 2368af514c044bf90048e9bb916024198f9bc5dcb3f5florian 2369af514c044bf90048e9bb916024198f9bc5dcb3f5florian vassert(arity == 4); 2370af514c044bf90048e9bb916024198f9bc5dcb3f5florian 2371af514c044bf90048e9bb916024198f9bc5dcb3f5florian cc_op_expr = args[0]; 2372af514c044bf90048e9bb916024198f9bc5dcb3f5florian 2373af514c044bf90048e9bb916024198f9bc5dcb3f5florian /* The necessary requirement for all optimizations here is that 2374af514c044bf90048e9bb916024198f9bc5dcb3f5florian cc_op is constant. So check that upfront. */ 2375af514c044bf90048e9bb916024198f9bc5dcb3f5florian if (! isC64(cc_op_expr)) return NULL; 2376af514c044bf90048e9bb916024198f9bc5dcb3f5florian 2377af514c044bf90048e9bb916024198f9bc5dcb3f5florian cc_op = cc_op_expr->Iex.Const.con->Ico.U64; 2378af514c044bf90048e9bb916024198f9bc5dcb3f5florian cc_dep1 = args[1]; 2379af514c044bf90048e9bb916024198f9bc5dcb3f5florian 2380af514c044bf90048e9bb916024198f9bc5dcb3f5florian if (cc_op == S390_CC_OP_BITWISE) { 2381af514c044bf90048e9bb916024198f9bc5dcb3f5florian return unop(Iop_1Uto32, 2382af514c044bf90048e9bb916024198f9bc5dcb3f5florian binop(Iop_CmpNE64, cc_dep1, mkU64(0))); 2383af514c044bf90048e9bb916024198f9bc5dcb3f5florian } 2384af514c044bf90048e9bb916024198f9bc5dcb3f5florian 2385af514c044bf90048e9bb916024198f9bc5dcb3f5florian if (cc_op == S390_CC_OP_SET) { 2386af514c044bf90048e9bb916024198f9bc5dcb3f5florian return unop(Iop_64to32, cc_dep1); 2387af514c044bf90048e9bb916024198f9bc5dcb3f5florian } 2388af514c044bf90048e9bb916024198f9bc5dcb3f5florian 2389af514c044bf90048e9bb916024198f9bc5dcb3f5florian goto missed; 2390af514c044bf90048e9bb916024198f9bc5dcb3f5florian } 2391af514c044bf90048e9bb916024198f9bc5dcb3f5florian 2392af514c044bf90048e9bb916024198f9bc5dcb3f5florianmissed: 23932019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return NULL; 23942019a976f07ff418dde2dfc7cc74667ef66d7764sewardj} 23952019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 23962019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*---------------------------------------------------------------*/ 23972019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*--- end guest_s390_helpers.c ---*/ 23982019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*---------------------------------------------------------------*/ 2399