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 11785952d4bf502fa756b2ac58595fd31fe0f88559sewardj Copyright IBM Corp. 2010-2015 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 155ca2c3c75784d35d136fc7c952717cdee5063c193sewardjguest_s390x_state_requires_precise_mem_exns ( 156ca2c3c75784d35d136fc7c952717cdee5063c193sewardj Int minoff, Int maxoff, VexRegisterUpdates pxControl 157ca2c3c75784d35d136fc7c952717cdee5063c193sewardj) 1582019a976f07ff418dde2dfc7cc74667ef66d7764sewardj{ 159606878860623daa234c68fff81aade73059aaafbsewardj Int lr_min = S390X_GUEST_OFFSET(guest_LR); 1602019a976f07ff418dde2dfc7cc74667ef66d7764sewardj Int lr_max = lr_min + 8 - 1; 161606878860623daa234c68fff81aade73059aaafbsewardj Int sp_min = S390X_GUEST_OFFSET(guest_SP); 1622019a976f07ff418dde2dfc7cc74667ef66d7764sewardj Int sp_max = sp_min + 8 - 1; 163606878860623daa234c68fff81aade73059aaafbsewardj Int fp_min = S390X_GUEST_OFFSET(guest_FP); 1642019a976f07ff418dde2dfc7cc74667ef66d7764sewardj Int fp_max = fp_min + 8 - 1; 165e88b3c94d4e3bf0f40123ffe162dd60e50580366florian Int ia_min = S390X_GUEST_OFFSET(guest_IA); 1662019a976f07ff418dde2dfc7cc74667ef66d7764sewardj Int ia_max = ia_min + 8 - 1; 1672019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 1686c46befd9eb90c1b6e739926c1fa335cba75bf46philippe if (maxoff < sp_min || minoff > sp_max) { 1696c46befd9eb90c1b6e739926c1fa335cba75bf46philippe /* No overlap with SP */ 170ca2c3c75784d35d136fc7c952717cdee5063c193sewardj if (pxControl == VexRegUpdSpAtMemAccess) 1716c46befd9eb90c1b6e739926c1fa335cba75bf46philippe return False; // We only need to check stack pointer. 1722019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } else { 1732019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return True; 1742019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 1752019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 1766c46befd9eb90c1b6e739926c1fa335cba75bf46philippe if (maxoff < lr_min || minoff > lr_max) { 1776c46befd9eb90c1b6e739926c1fa335cba75bf46philippe /* No overlap with LR */ 1782019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } else { 1792019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return True; 1802019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 1812019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 1822019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (maxoff < fp_min || minoff > fp_max) { 1832019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* No overlap with FP */ 1842019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } else { 1852019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return True; 1862019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 1872019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 1882019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (maxoff < ia_min || minoff > ia_max) { 1892019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* No overlap with IA */ 1902019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } else { 1912019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return True; 1922019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 1932019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 1942019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return False; 1952019a976f07ff418dde2dfc7cc74667ef66d7764sewardj} 1962019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 1972019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 1982019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#define ALWAYSDEFD(field) \ 199e88b3c94d4e3bf0f40123ffe162dd60e50580366florian { S390X_GUEST_OFFSET(field), \ 2002019a976f07ff418dde2dfc7cc74667ef66d7764sewardj (sizeof ((VexGuestS390XState*)0)->field) } 2012019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 2022019a976f07ff418dde2dfc7cc74667ef66d7764sewardjVexGuestLayout s390xGuest_layout = { 2032019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 2042019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Total size of the guest state, in bytes. */ 2052019a976f07ff418dde2dfc7cc74667ef66d7764sewardj .total_sizeB = sizeof(VexGuestS390XState), 2062019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 2072019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Describe the stack pointer. */ 208606878860623daa234c68fff81aade73059aaafbsewardj .offset_SP = S390X_GUEST_OFFSET(guest_SP), 2092019a976f07ff418dde2dfc7cc74667ef66d7764sewardj .sizeof_SP = 8, 2102019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 2112019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Describe the frame pointer. */ 212606878860623daa234c68fff81aade73059aaafbsewardj .offset_FP = S390X_GUEST_OFFSET(guest_FP), 2132019a976f07ff418dde2dfc7cc74667ef66d7764sewardj .sizeof_FP = 8, 2142019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 2152019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Describe the instruction pointer. */ 216e88b3c94d4e3bf0f40123ffe162dd60e50580366florian .offset_IP = S390X_GUEST_OFFSET(guest_IA), 2172019a976f07ff418dde2dfc7cc74667ef66d7764sewardj .sizeof_IP = 8, 2182019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 2192019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Describe any sections to be regarded by Memcheck as 2202019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 'always-defined'. */ 2212019a976f07ff418dde2dfc7cc74667ef66d7764sewardj .n_alwaysDefd = 9, 2222019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 2232019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Flags thunk: OP and NDEP are always defined, whereas DEP1 2242019a976f07ff418dde2dfc7cc74667ef66d7764sewardj and DEP2 have to be tracked. See detailed comment in 2252019a976f07ff418dde2dfc7cc74667ef66d7764sewardj gdefs.h on meaning of thunk fields. */ 2262019a976f07ff418dde2dfc7cc74667ef66d7764sewardj .alwaysDefd = { 2272019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* 0 */ ALWAYSDEFD(guest_CC_OP), /* generic */ 2282019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* 1 */ ALWAYSDEFD(guest_CC_NDEP), /* generic */ 2296ef84bed9bb3af22060eb1759788034602bbcc88florian /* 2 */ ALWAYSDEFD(guest_EMNOTE), /* generic */ 23005f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj /* 3 */ ALWAYSDEFD(guest_CMSTART), /* generic */ 23105f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj /* 4 */ ALWAYSDEFD(guest_CMLEN), /* generic */ 2322019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* 5 */ ALWAYSDEFD(guest_IP_AT_SYSCALL), /* generic */ 2332019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* 6 */ ALWAYSDEFD(guest_IA), /* control reg */ 2342019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* 7 */ ALWAYSDEFD(guest_fpc), /* control reg */ 2352019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* 8 */ ALWAYSDEFD(guest_counter), /* internal usage register */ 2362019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 2372019a976f07ff418dde2dfc7cc74667ef66d7764sewardj}; 2382019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 2392019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*------------------------------------------------------------*/ 2402019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*--- Dirty helper for EXecute ---*/ 2412019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*------------------------------------------------------------*/ 2422019a976f07ff418dde2dfc7cc74667ef66d7764sewardjvoid 2432019a976f07ff418dde2dfc7cc74667ef66d7764sewardjs390x_dirtyhelper_EX(ULong torun) 2442019a976f07ff418dde2dfc7cc74667ef66d7764sewardj{ 2452019a976f07ff418dde2dfc7cc74667ef66d7764sewardj last_execute_target = torun; 2462019a976f07ff418dde2dfc7cc74667ef66d7764sewardj} 2472019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 2481e5fea63aab1f94925afd49d74560917b37fa505sewardj 2491e5fea63aab1f94925afd49d74560917b37fa505sewardj/*------------------------------------------------------------*/ 2501e5fea63aab1f94925afd49d74560917b37fa505sewardj/*--- Dirty helper for Clock instructions ---*/ 2511e5fea63aab1f94925afd49d74560917b37fa505sewardj/*------------------------------------------------------------*/ 2521e5fea63aab1f94925afd49d74560917b37fa505sewardj#if defined(VGA_s390x) 253ae88411aaa8e0b99032fb0bdb04eec21edc54d88florianULong 254ae88411aaa8e0b99032fb0bdb04eec21edc54d88florians390x_dirtyhelper_STCK(ULong *addr) 2551e5fea63aab1f94925afd49d74560917b37fa505sewardj{ 256ffbd84dd2205b38d45f3ce13d594787a7c62fd6cflorian UInt cc; 2571e5fea63aab1f94925afd49d74560917b37fa505sewardj 2581e5fea63aab1f94925afd49d74560917b37fa505sewardj asm volatile("stck %0\n" 2591e5fea63aab1f94925afd49d74560917b37fa505sewardj "ipm %1\n" 2601e5fea63aab1f94925afd49d74560917b37fa505sewardj "srl %1,28\n" 2611e5fea63aab1f94925afd49d74560917b37fa505sewardj : "+Q" (*addr), "=d" (cc) : : "cc"); 2621e5fea63aab1f94925afd49d74560917b37fa505sewardj return cc; 2631e5fea63aab1f94925afd49d74560917b37fa505sewardj} 2641e5fea63aab1f94925afd49d74560917b37fa505sewardj 265ae88411aaa8e0b99032fb0bdb04eec21edc54d88florianULong 266ae88411aaa8e0b99032fb0bdb04eec21edc54d88florians390x_dirtyhelper_STCKE(ULong *addr) 2671e5fea63aab1f94925afd49d74560917b37fa505sewardj{ 268ffbd84dd2205b38d45f3ce13d594787a7c62fd6cflorian UInt cc; 2691e5fea63aab1f94925afd49d74560917b37fa505sewardj 2701e5fea63aab1f94925afd49d74560917b37fa505sewardj asm volatile("stcke %0\n" 2711e5fea63aab1f94925afd49d74560917b37fa505sewardj "ipm %1\n" 2721e5fea63aab1f94925afd49d74560917b37fa505sewardj "srl %1,28\n" 2731e5fea63aab1f94925afd49d74560917b37fa505sewardj : "+Q" (*addr), "=d" (cc) : : "cc"); 2741e5fea63aab1f94925afd49d74560917b37fa505sewardj return cc; 2751e5fea63aab1f94925afd49d74560917b37fa505sewardj} 2761e5fea63aab1f94925afd49d74560917b37fa505sewardj 2771e5fea63aab1f94925afd49d74560917b37fa505sewardjULong s390x_dirtyhelper_STCKF(ULong *addr) 2781e5fea63aab1f94925afd49d74560917b37fa505sewardj{ 279ffbd84dd2205b38d45f3ce13d594787a7c62fd6cflorian UInt cc; 2801e5fea63aab1f94925afd49d74560917b37fa505sewardj 2811e5fea63aab1f94925afd49d74560917b37fa505sewardj asm volatile(".insn s,0xb27c0000,%0\n" 2821e5fea63aab1f94925afd49d74560917b37fa505sewardj "ipm %1\n" 2831e5fea63aab1f94925afd49d74560917b37fa505sewardj "srl %1,28\n" 2841e5fea63aab1f94925afd49d74560917b37fa505sewardj : "+Q" (*addr), "=d" (cc) : : "cc"); 2851e5fea63aab1f94925afd49d74560917b37fa505sewardj return cc; 2861e5fea63aab1f94925afd49d74560917b37fa505sewardj} 2871e5fea63aab1f94925afd49d74560917b37fa505sewardj#else 2881e5fea63aab1f94925afd49d74560917b37fa505sewardjULong s390x_dirtyhelper_STCK(ULong *addr) {return 3;} 2891e5fea63aab1f94925afd49d74560917b37fa505sewardjULong s390x_dirtyhelper_STCKF(ULong *addr) {return 3;} 2901e5fea63aab1f94925afd49d74560917b37fa505sewardjULong s390x_dirtyhelper_STCKE(ULong *addr) {return 3;} 2911e5fea63aab1f94925afd49d74560917b37fa505sewardj#endif /* VGA_s390x */ 2921e5fea63aab1f94925afd49d74560917b37fa505sewardj 2932019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*------------------------------------------------------------*/ 294933065d4f3548466da4666c5cfda7e5eaff93759florian/*--- Dirty helper for Store Facility instruction ---*/ 295933065d4f3548466da4666c5cfda7e5eaff93759florian/*------------------------------------------------------------*/ 296933065d4f3548466da4666c5cfda7e5eaff93759florian#if defined(VGA_s390x) 297b7def2222c08b119df85bc7231bf0e6806f3a1a6florianstatic void 298b7def2222c08b119df85bc7231bf0e6806f3a1a6florians390_set_facility_bit(ULong *addr, UInt bitno, UInt value) 299b7def2222c08b119df85bc7231bf0e6806f3a1a6florian{ 300b7def2222c08b119df85bc7231bf0e6806f3a1a6florian addr += bitno / 64; 301b7def2222c08b119df85bc7231bf0e6806f3a1a6florian bitno = bitno % 64; 302b7def2222c08b119df85bc7231bf0e6806f3a1a6florian 303b7def2222c08b119df85bc7231bf0e6806f3a1a6florian ULong mask = 1; 304b7def2222c08b119df85bc7231bf0e6806f3a1a6florian mask <<= (63 - bitno); 305b7def2222c08b119df85bc7231bf0e6806f3a1a6florian 306b7def2222c08b119df85bc7231bf0e6806f3a1a6florian if (value == 1) { 307b7def2222c08b119df85bc7231bf0e6806f3a1a6florian *addr |= mask; // set 308b7def2222c08b119df85bc7231bf0e6806f3a1a6florian } else { 309b7def2222c08b119df85bc7231bf0e6806f3a1a6florian *addr &= ~mask; // clear 310b7def2222c08b119df85bc7231bf0e6806f3a1a6florian } 311b7def2222c08b119df85bc7231bf0e6806f3a1a6florian} 312b7def2222c08b119df85bc7231bf0e6806f3a1a6florian 313933065d4f3548466da4666c5cfda7e5eaff93759florianULong 314ae88411aaa8e0b99032fb0bdb04eec21edc54d88florians390x_dirtyhelper_STFLE(VexGuestS390XState *guest_state, ULong *addr) 315933065d4f3548466da4666c5cfda7e5eaff93759florian{ 316933065d4f3548466da4666c5cfda7e5eaff93759florian ULong hoststfle[S390_NUM_FACILITY_DW], cc, num_dw, i; 317933065d4f3548466da4666c5cfda7e5eaff93759florian register ULong reg0 asm("0") = guest_state->guest_r0 & 0xF; /* r0[56:63] */ 318933065d4f3548466da4666c5cfda7e5eaff93759florian 319933065d4f3548466da4666c5cfda7e5eaff93759florian /* We cannot store more than S390_NUM_FACILITY_DW 320933065d4f3548466da4666c5cfda7e5eaff93759florian (and it makes not much sense to do so anyhow) */ 321933065d4f3548466da4666c5cfda7e5eaff93759florian if (reg0 > S390_NUM_FACILITY_DW - 1) 322933065d4f3548466da4666c5cfda7e5eaff93759florian reg0 = S390_NUM_FACILITY_DW - 1; 323933065d4f3548466da4666c5cfda7e5eaff93759florian 324933065d4f3548466da4666c5cfda7e5eaff93759florian num_dw = reg0 + 1; /* number of double words written */ 325933065d4f3548466da4666c5cfda7e5eaff93759florian 326933065d4f3548466da4666c5cfda7e5eaff93759florian asm volatile(" .insn s,0xb2b00000,%0\n" /* stfle */ 327933065d4f3548466da4666c5cfda7e5eaff93759florian "ipm %2\n" 328933065d4f3548466da4666c5cfda7e5eaff93759florian "srl %2,28\n" 329933065d4f3548466da4666c5cfda7e5eaff93759florian : "=m" (hoststfle), "+d"(reg0), "=d"(cc) : : "cc", "memory"); 330933065d4f3548466da4666c5cfda7e5eaff93759florian 331933065d4f3548466da4666c5cfda7e5eaff93759florian /* Update guest register 0 with what STFLE set r0 to */ 332933065d4f3548466da4666c5cfda7e5eaff93759florian guest_state->guest_r0 = reg0; 333933065d4f3548466da4666c5cfda7e5eaff93759florian 334b7def2222c08b119df85bc7231bf0e6806f3a1a6florian /* Set default: VM facilities = host facilities */ 335933065d4f3548466da4666c5cfda7e5eaff93759florian for (i = 0; i < num_dw; ++i) 336ae88411aaa8e0b99032fb0bdb04eec21edc54d88florian addr[i] = hoststfle[i]; 337933065d4f3548466da4666c5cfda7e5eaff93759florian 338b7def2222c08b119df85bc7231bf0e6806f3a1a6florian /* Now adjust the VM facilities according to what the VM supports */ 339b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_LDISP, 1); 340b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_EIMM, 1); 341b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_ETF2, 1); 342b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_ETF3, 1); 343b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_GIE, 1); 344b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_EXEXT, 1); 345b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_HIGHW, 1); 346b7def2222c08b119df85bc7231bf0e6806f3a1a6florian 347b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_HFPMAS, 0); 348b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_HFPUNX, 0); 349b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_XCPUT, 0); 350b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_MSA, 0); 351b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_PENH, 0); 352b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_DFP, 0); 353b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_PFPO, 0); 354b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_DFPZC, 0); 355b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_MISC, 0); 356b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_CTREXE, 0); 357b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_TREXE, 0); 358b7def2222c08b119df85bc7231bf0e6806f3a1a6florian s390_set_facility_bit(addr, S390_FAC_MSA4, 0); 359b7def2222c08b119df85bc7231bf0e6806f3a1a6florian 360933065d4f3548466da4666c5cfda7e5eaff93759florian return cc; 361933065d4f3548466da4666c5cfda7e5eaff93759florian} 362933065d4f3548466da4666c5cfda7e5eaff93759florian 363933065d4f3548466da4666c5cfda7e5eaff93759florian#else 364933065d4f3548466da4666c5cfda7e5eaff93759florian 365933065d4f3548466da4666c5cfda7e5eaff93759florianULong 366ae88411aaa8e0b99032fb0bdb04eec21edc54d88florians390x_dirtyhelper_STFLE(VexGuestS390XState *guest_state, ULong *addr) 367933065d4f3548466da4666c5cfda7e5eaff93759florian{ 368933065d4f3548466da4666c5cfda7e5eaff93759florian return 3; 369933065d4f3548466da4666c5cfda7e5eaff93759florian} 370933065d4f3548466da4666c5cfda7e5eaff93759florian#endif /* VGA_s390x */ 371933065d4f3548466da4666c5cfda7e5eaff93759florian 372a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian/*------------------------------------------------------------*/ 373a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian/*--- Dirty helper for the "convert unicode" insn family. ---*/ 374a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian/*------------------------------------------------------------*/ 375a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorianvoid 376a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorians390x_dirtyhelper_CUxy(UChar *address, ULong data, ULong num_bytes) 377a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian{ 378a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian UInt i; 379a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 380a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian vassert(num_bytes >= 1 && num_bytes <= 4); 381a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 382a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian /* Store the least significant NUM_BYTES bytes in DATA left to right 383a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian at ADDRESS. */ 384a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian for (i = 1; i <= num_bytes; ++i) { 385a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian address[num_bytes - i] = data & 0xff; 386a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian data >>= 8; 387a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian } 388a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian} 389a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 390a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 391a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian/*------------------------------------------------------------*/ 392a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian/*--- Clean helper for CU21. ---*/ 393a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian/*------------------------------------------------------------*/ 394a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 395a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian/* The function performs a CU21 operation. It returns three things 396a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian encoded in an ULong value: 397a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian - the converted bytes (at most 4) 398a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian - the number of converted bytes 399a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian - an indication whether LOW_SURROGATE, if any, is invalid 400a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 401a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 64 48 16 8 0 402a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian +-------+-----------------+-----------+-----------------------+ 403a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian | 0x0 | converted bytes | num_bytes | invalid_low_surrogate | 404a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian +-------+-----------------+-----------+-----------------------+ 405a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian*/ 406a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorianULong 407a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorians390_do_cu21(UInt srcval, UInt low_surrogate) 408a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian{ 409a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian ULong retval = 0; // shut up gcc 410ae88411aaa8e0b99032fb0bdb04eec21edc54d88florian UInt b1, b2, b3, b4, num_bytes, invalid_low_surrogate = 0; 411a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 412a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian srcval &= 0xffff; 413a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 414a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian /* Determine the number of bytes in the converted value */ 415a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian if (srcval <= 0x007f) 416a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian num_bytes = 1; 417a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian else if (srcval >= 0x0080 && srcval <= 0x07ff) 418a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian num_bytes = 2; 419a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian else if ((srcval >= 0x0800 && srcval <= 0xd7ff) || 420a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian (srcval >= 0xdc00 && srcval <= 0xffff)) 421a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian num_bytes = 3; 422a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian else 423a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian num_bytes = 4; 424a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 425a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian /* Determine UTF-8 bytes according to calculated num_bytes */ 426a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian switch (num_bytes){ 427a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian case 1: 428a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian retval = srcval; 429a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian break; 430a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 431a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian case 2: 432a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian /* order of bytes left to right: b1, b2 */ 433a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b1 = 0xc0; 434a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b1 |= srcval >> 6; 435a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 436a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b2 = 0x80; 437a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b2 |= srcval & 0x3f; 438a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 439a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian retval = (b1 << 8) | b2; 440a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian break; 441a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 442a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian case 3: 443a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian /* order of bytes left to right: b1, b2, b3 */ 444a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b1 = 0xe0; 445a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b1 |= srcval >> 12; 446a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 447a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b2 = 0x80; 448a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b2 |= (srcval >> 6) & 0x3f; 449a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 450a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b3 = 0x80; 451a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b3 |= srcval & 0x3f; 452a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 453a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian retval = (b1 << 16) | (b2 << 8) | b3; 454a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian break; 455a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 456a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian case 4: { 457a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian /* order of bytes left to right: b1, b2, b3, b4 */ 458a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian UInt high_surrogate = srcval; 459a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian UInt uvwxy = ((high_surrogate >> 6) & 0xf) + 1; // abcd + 1 460a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 461a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b1 = 0xf0; 462a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b1 |= uvwxy >> 2; // uvw 463a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 464a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b2 = 0x80; 465a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b2 |= (uvwxy & 0x3) << 4; // xy 466a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b2 |= (high_surrogate >> 2) & 0xf; // efgh 467a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 468a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b3 = 0x80; 469a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b3 |= (high_surrogate & 0x3) << 4; // ij 470a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b3 |= (low_surrogate >> 6) & 0xf; // klmn 471a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 472a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b4 = 0x80; 473a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian b4 |= low_surrogate & 0x3f; 474a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 475a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian retval = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4; 476a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 477a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian invalid_low_surrogate = (low_surrogate & 0xfc00) != 0xdc00; 478a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian break; 479a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian } 480a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian } 481a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 482a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian /* At this point RETVAL contains the converted bytes. 483a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian Build up the final return value. */ 484a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian return (retval << 16) | (num_bytes << 8) | invalid_low_surrogate; 485a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian} 486a0100c9e17c7cd5a2373d2b3e306d4cb79cbbd1eflorian 487e711c805f1de40b8fafce36d04e589c6a5074e9aflorian 488e711c805f1de40b8fafce36d04e589c6a5074e9aflorian/*------------------------------------------------------------*/ 4892a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian/*--- Clean helper for CU24. ---*/ 4902a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian/*------------------------------------------------------------*/ 4912a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian 4922a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian/* The function performs a CU24 operation. It returns two things 4932a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian encoded in an ULong value: 4942a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian - the 4 converted bytes 4952a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian - an indication whether LOW_SURROGATE, if any, is invalid 4962a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian 4972a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian 64 40 8 0 4982a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian +------------------------+-----------------------+ 4992a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian | 0x0 | converted bytes | invalid_low_surrogate | 5002a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian +------------------------+-----------------------+ 5012a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian*/ 5022a415a1a1f656e56f88c65f12a37b2658cb45e0bflorianULong 5032a415a1a1f656e56f88c65f12a37b2658cb45e0bflorians390_do_cu24(UInt srcval, UInt low_surrogate) 5042a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian{ 5052a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian ULong retval; 5062a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian UInt invalid_low_surrogate = 0; 5072a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian 5082a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian srcval &= 0xffff; 5092a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian 5102a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian if ((srcval >= 0x0000 && srcval <= 0xd7ff) || 5112a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian (srcval >= 0xdc00 && srcval <= 0xffff)) { 5122a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian retval = srcval; 5132a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian } else { 5142a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian /* D800 - DBFF */ 5152a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian UInt high_surrogate = srcval; 5162a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian UInt uvwxy = ((high_surrogate >> 6) & 0xf) + 1; // abcd + 1 5172a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian UInt efghij = high_surrogate & 0x3f; 5182a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian UInt klmnoprst = low_surrogate & 0x3ff; 5192a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian 5202a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian retval = (uvwxy << 16) | (efghij << 10) | klmnoprst; 5212a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian 5222a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian invalid_low_surrogate = (low_surrogate & 0xfc00) != 0xdc00; 5232a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian } 5242a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian 5252a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian /* At this point RETVAL contains the converted bytes. 5262a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian Build up the final return value. */ 5272a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian return (retval << 8) | invalid_low_surrogate; 5282a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian} 5292a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian 5302a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian 5312a415a1a1f656e56f88c65f12a37b2658cb45e0bflorian/*------------------------------------------------------------*/ 532956194bc1039e9dc43dac4b18ab1fdd5054a5671florian/*--- Clean helper for CU42. ---*/ 533956194bc1039e9dc43dac4b18ab1fdd5054a5671florian/*------------------------------------------------------------*/ 534956194bc1039e9dc43dac4b18ab1fdd5054a5671florian 535956194bc1039e9dc43dac4b18ab1fdd5054a5671florian/* The function performs a CU42 operation. It returns three things 536956194bc1039e9dc43dac4b18ab1fdd5054a5671florian encoded in an ULong value: 537956194bc1039e9dc43dac4b18ab1fdd5054a5671florian - the converted bytes (at most 4) 538956194bc1039e9dc43dac4b18ab1fdd5054a5671florian - the number of converted bytes (2 or 4; 0 if invalid character) 539956194bc1039e9dc43dac4b18ab1fdd5054a5671florian - an indication whether the UTF-32 character is invalid 540956194bc1039e9dc43dac4b18ab1fdd5054a5671florian 541956194bc1039e9dc43dac4b18ab1fdd5054a5671florian 64 48 16 8 0 542956194bc1039e9dc43dac4b18ab1fdd5054a5671florian +-------+-----------------+-----------+-------------------+ 543956194bc1039e9dc43dac4b18ab1fdd5054a5671florian | 0x0 | converted bytes | num_bytes | invalid_character | 544956194bc1039e9dc43dac4b18ab1fdd5054a5671florian +-------+-----------------+-----------+-------------------+ 545956194bc1039e9dc43dac4b18ab1fdd5054a5671florian*/ 546956194bc1039e9dc43dac4b18ab1fdd5054a5671florianULong 547956194bc1039e9dc43dac4b18ab1fdd5054a5671florians390_do_cu42(UInt srcval) 548956194bc1039e9dc43dac4b18ab1fdd5054a5671florian{ 549956194bc1039e9dc43dac4b18ab1fdd5054a5671florian ULong retval; 550956194bc1039e9dc43dac4b18ab1fdd5054a5671florian UInt num_bytes, invalid_character = 0; 551956194bc1039e9dc43dac4b18ab1fdd5054a5671florian 552956194bc1039e9dc43dac4b18ab1fdd5054a5671florian if ((srcval >= 0x0000 && srcval <= 0xd7ff) || 553956194bc1039e9dc43dac4b18ab1fdd5054a5671florian (srcval >= 0xdc00 && srcval <= 0xffff)) { 554956194bc1039e9dc43dac4b18ab1fdd5054a5671florian retval = srcval; 555956194bc1039e9dc43dac4b18ab1fdd5054a5671florian num_bytes = 2; 556956194bc1039e9dc43dac4b18ab1fdd5054a5671florian } else if (srcval >= 0x00010000 && srcval <= 0x0010FFFF) { 557956194bc1039e9dc43dac4b18ab1fdd5054a5671florian UInt uvwxy = srcval >> 16; 558956194bc1039e9dc43dac4b18ab1fdd5054a5671florian UInt abcd = (uvwxy - 1) & 0xf; 559956194bc1039e9dc43dac4b18ab1fdd5054a5671florian UInt efghij = (srcval >> 10) & 0x3f; 560956194bc1039e9dc43dac4b18ab1fdd5054a5671florian 561956194bc1039e9dc43dac4b18ab1fdd5054a5671florian UInt high_surrogate = (0xd8 << 8) | (abcd << 6) | efghij; 562956194bc1039e9dc43dac4b18ab1fdd5054a5671florian UInt low_surrogate = (0xdc << 8) | (srcval & 0x3ff); 563956194bc1039e9dc43dac4b18ab1fdd5054a5671florian 564956194bc1039e9dc43dac4b18ab1fdd5054a5671florian retval = (high_surrogate << 16) | low_surrogate; 565956194bc1039e9dc43dac4b18ab1fdd5054a5671florian num_bytes = 4; 566956194bc1039e9dc43dac4b18ab1fdd5054a5671florian } else { 567956194bc1039e9dc43dac4b18ab1fdd5054a5671florian /* D800 - DBFF or 00110000 - FFFFFFFF */ 568956194bc1039e9dc43dac4b18ab1fdd5054a5671florian invalid_character = 1; 569956194bc1039e9dc43dac4b18ab1fdd5054a5671florian retval = num_bytes = 0; /* does not matter; not used */ 570956194bc1039e9dc43dac4b18ab1fdd5054a5671florian } 571956194bc1039e9dc43dac4b18ab1fdd5054a5671florian 572956194bc1039e9dc43dac4b18ab1fdd5054a5671florian /* At this point RETVAL contains the converted bytes. 573956194bc1039e9dc43dac4b18ab1fdd5054a5671florian Build up the final return value. */ 574956194bc1039e9dc43dac4b18ab1fdd5054a5671florian return (retval << 16) | (num_bytes << 8) | invalid_character; 575956194bc1039e9dc43dac4b18ab1fdd5054a5671florian} 576956194bc1039e9dc43dac4b18ab1fdd5054a5671florian 577956194bc1039e9dc43dac4b18ab1fdd5054a5671florian 578956194bc1039e9dc43dac4b18ab1fdd5054a5671florian/*------------------------------------------------------------*/ 579af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian/*--- Clean helper for CU41. ---*/ 580af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian/*------------------------------------------------------------*/ 581af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian 582af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian/* The function performs a CU41 operation. It returns three things 583af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian encoded in an ULong value: 584af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian - the converted bytes (at most 4) 585af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian - the number of converted bytes (1, 2, 3, or 4; 0 if invalid character) 586af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian - an indication whether the UTF-32 character is invalid 587af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian 588af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian 64 48 16 8 0 589af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian +-------+-----------------+-----------+-------------------+ 590af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian | 0x0 | converted bytes | num_bytes | invalid_character | 591af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian +-------+-----------------+-----------+-------------------+ 592af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian*/ 593af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florianULong 594af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florians390_do_cu41(UInt srcval) 595af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian{ 596af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian ULong retval; 597af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt num_bytes, invalid_character = 0; 598af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian 599af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian if (srcval <= 0x7f) { 600af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian retval = srcval; 601af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian num_bytes = 1; 602af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian } else if (srcval >= 0x80 && srcval <= 0x7ff) { 603af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt fghij = srcval >> 6; 604af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt klmnop = srcval & 0x3f; 605af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt byte1 = (0xc0 | fghij); 606af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt byte2 = (0x80 | klmnop); 607af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian 608af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian retval = (byte1 << 8) | byte2; 609af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian num_bytes = 2; 610af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian } else if ((srcval >= 0x800 && srcval <= 0xd7ff) || 611af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian (srcval >= 0xdc00 && srcval <= 0xffff)) { 612af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt abcd = srcval >> 12; 613af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt efghij = (srcval >> 6) & 0x3f; 614af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt klmnop = srcval & 0x3f; 615af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt byte1 = 0xe0 | abcd; 616af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt byte2 = 0x80 | efghij; 617af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt byte3 = 0x80 | klmnop; 618af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian 619af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian retval = (byte1 << 16) | (byte2 << 8) | byte3; 620af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian num_bytes = 3; 621af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian } else if (srcval >= 0x10000 && srcval <= 0x10ffff) { 622af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt uvw = (srcval >> 18) & 0x7; 623af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt xy = (srcval >> 16) & 0x3; 624af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt efgh = (srcval >> 12) & 0xf; 625af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt ijklmn = (srcval >> 6) & 0x3f; 626af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt opqrst = srcval & 0x3f; 627af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt byte1 = 0xf0 | uvw; 628af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt byte2 = 0x80 | (xy << 4) | efgh; 629af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt byte3 = 0x80 | ijklmn; 630af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian UInt byte4 = 0x80 | opqrst; 631af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian 632af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian retval = (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4; 633af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian num_bytes = 4; 634af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian } else { 635af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian /* d800 ... dbff or 00110000 ... ffffffff */ 636af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian invalid_character = 1; 637af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian 638af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian retval = 0; 639af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian num_bytes = 0; 640af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian } 641af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian 642af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian /* At this point RETVAL contains the converted bytes. 643af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian Build up the final return value. */ 644af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian return (retval << 16) | (num_bytes << 8) | invalid_character; 645af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian} 646af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian 647af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian 648af2194f3e45a0bd6db4c4857d1f2be21f857d3f3florian/*------------------------------------------------------------*/ 6496d9b9b23ea3541501ea98a39e2d757892a79c78aflorian/*--- Clean helpers for CU12. ---*/ 6506d9b9b23ea3541501ea98a39e2d757892a79c78aflorian/*------------------------------------------------------------*/ 6516d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 6526d9b9b23ea3541501ea98a39e2d757892a79c78aflorian/* The function looks at the first byte of an UTF-8 character and returns 6536d9b9b23ea3541501ea98a39e2d757892a79c78aflorian two things encoded in an ULong value: 6546d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 6556d9b9b23ea3541501ea98a39e2d757892a79c78aflorian - the number of bytes that need to be read 6566d9b9b23ea3541501ea98a39e2d757892a79c78aflorian - an indication whether the UTF-8 character is invalid 6576d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 6586d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 64 16 8 0 6596d9b9b23ea3541501ea98a39e2d757892a79c78aflorian +-------------------+-------------------+ 6606d9b9b23ea3541501ea98a39e2d757892a79c78aflorian | 0x0 | num_bytes | invalid_character | 6616d9b9b23ea3541501ea98a39e2d757892a79c78aflorian +-------+-----------+-------------------+ 6626d9b9b23ea3541501ea98a39e2d757892a79c78aflorian*/ 6636d9b9b23ea3541501ea98a39e2d757892a79c78aflorianULong 6643f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florians390_do_cu12_cu14_helper1(UInt byte, UInt etf3_and_m3_is_1) 6656d9b9b23ea3541501ea98a39e2d757892a79c78aflorian{ 6666d9b9b23ea3541501ea98a39e2d757892a79c78aflorian vassert(byte <= 0xff); 6676d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 6686d9b9b23ea3541501ea98a39e2d757892a79c78aflorian /* Check whether the character is invalid */ 6696d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if (byte >= 0x80 && byte <= 0xbf) return 1; 6706d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if (byte >= 0xf8) return 1; 6716d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 6726d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if (etf3_and_m3_is_1) { 6736d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if (byte == 0xc0 || byte == 0xc1) return 1; 6746d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if (byte >= 0xf5 && byte <= 0xf7) return 1; 6756d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 6766d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 6776d9b9b23ea3541501ea98a39e2d757892a79c78aflorian /* Character is valid */ 6786d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if (byte <= 0x7f) return 1 << 8; // 1 byte 6796d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if (byte <= 0xdf) return 2 << 8; // 2 bytes 6806d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if (byte <= 0xef) return 3 << 8; // 3 bytes 6816d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 6826d9b9b23ea3541501ea98a39e2d757892a79c78aflorian return 4 << 8; // 4 bytes 6836d9b9b23ea3541501ea98a39e2d757892a79c78aflorian} 6846d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 6853f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian/* The function performs a CU12 or CU14 operation. BYTE1, BYTE2, etc are the 6866d9b9b23ea3541501ea98a39e2d757892a79c78aflorian bytes as read from the input stream, left to right. BYTE1 is a valid 6876d9b9b23ea3541501ea98a39e2d757892a79c78aflorian byte. The function returns three things encoded in an ULong value: 6886d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 6896d9b9b23ea3541501ea98a39e2d757892a79c78aflorian - the converted bytes 6906d9b9b23ea3541501ea98a39e2d757892a79c78aflorian - the number of converted bytes (2 or 4; 0 if invalid character) 6916d9b9b23ea3541501ea98a39e2d757892a79c78aflorian - an indication whether the UTF-16 character is invalid 6926d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 6936d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 64 48 16 8 0 6946d9b9b23ea3541501ea98a39e2d757892a79c78aflorian +-------+-----------------+-----------+-------------------+ 6956d9b9b23ea3541501ea98a39e2d757892a79c78aflorian | 0x0 | converted bytes | num_bytes | invalid_character | 6966d9b9b23ea3541501ea98a39e2d757892a79c78aflorian +-------+-----------------+-----------+-------------------+ 6976d9b9b23ea3541501ea98a39e2d757892a79c78aflorian*/ 6983f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florianstatic ULong 6993f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florians390_do_cu12_cu14_helper2(UInt byte1, UInt byte2, UInt byte3, UInt byte4, 7003f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian ULong stuff, Bool is_cu12) 7016d9b9b23ea3541501ea98a39e2d757892a79c78aflorian{ 7023f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian UInt num_src_bytes = stuff >> 1, etf3_and_m3_is_1 = stuff & 0x1; 7036d9b9b23ea3541501ea98a39e2d757892a79c78aflorian UInt num_bytes = 0, invalid_character = 0; 7046d9b9b23ea3541501ea98a39e2d757892a79c78aflorian ULong retval = 0; 7056d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 7066d9b9b23ea3541501ea98a39e2d757892a79c78aflorian vassert(num_src_bytes <= 4); 7076d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 7086d9b9b23ea3541501ea98a39e2d757892a79c78aflorian switch (num_src_bytes) { 7096d9b9b23ea3541501ea98a39e2d757892a79c78aflorian case 1: 7106d9b9b23ea3541501ea98a39e2d757892a79c78aflorian num_bytes = 2; 7116d9b9b23ea3541501ea98a39e2d757892a79c78aflorian retval = byte1; 7126d9b9b23ea3541501ea98a39e2d757892a79c78aflorian break; 7136d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 7146d9b9b23ea3541501ea98a39e2d757892a79c78aflorian case 2: { 7156d9b9b23ea3541501ea98a39e2d757892a79c78aflorian /* Test validity */ 7166d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if (etf3_and_m3_is_1) { 7176d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if (byte2 < 0x80 || byte2 > 0xbf) { 7186d9b9b23ea3541501ea98a39e2d757892a79c78aflorian invalid_character = 1; 7196d9b9b23ea3541501ea98a39e2d757892a79c78aflorian break; 7206d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 7216d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 7226d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 7236d9b9b23ea3541501ea98a39e2d757892a79c78aflorian /* OK */ 7246d9b9b23ea3541501ea98a39e2d757892a79c78aflorian UInt fghij = byte1 & 0x1f; 7256d9b9b23ea3541501ea98a39e2d757892a79c78aflorian UInt klmnop = byte2 & 0x3f; 7266d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 7276d9b9b23ea3541501ea98a39e2d757892a79c78aflorian num_bytes = 2; 7286d9b9b23ea3541501ea98a39e2d757892a79c78aflorian retval = (fghij << 6) | klmnop; 7296d9b9b23ea3541501ea98a39e2d757892a79c78aflorian break; 7306d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 7316d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 7326d9b9b23ea3541501ea98a39e2d757892a79c78aflorian case 3: { 7336d9b9b23ea3541501ea98a39e2d757892a79c78aflorian /* Test validity */ 7346d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if (etf3_and_m3_is_1) { 7356d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if (byte1 == 0xe0) { 7366d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if ((byte2 < 0xa0 || byte2 > 0xbf) || 7376d9b9b23ea3541501ea98a39e2d757892a79c78aflorian (byte3 < 0x80 || byte3 > 0xbf)) { 7386d9b9b23ea3541501ea98a39e2d757892a79c78aflorian invalid_character = 1; 7396d9b9b23ea3541501ea98a39e2d757892a79c78aflorian break; 7406d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 7416d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 7426d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if ((byte1 >= 0xe1 && byte1 <= 0xec) || 7436d9b9b23ea3541501ea98a39e2d757892a79c78aflorian byte1 == 0xee || byte1 == 0xef) { 7446d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if ((byte2 < 0x80 || byte2 > 0xbf) || 7456d9b9b23ea3541501ea98a39e2d757892a79c78aflorian (byte3 < 0x80 || byte3 > 0xbf)) { 7466d9b9b23ea3541501ea98a39e2d757892a79c78aflorian invalid_character = 1; 7476d9b9b23ea3541501ea98a39e2d757892a79c78aflorian break; 7486d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 7496d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 7506d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if (byte1 == 0xed) { 7516d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if ((byte2 < 0x80 || byte2 > 0x9f) || 7526d9b9b23ea3541501ea98a39e2d757892a79c78aflorian (byte3 < 0x80 || byte3 > 0xbf)) { 7536d9b9b23ea3541501ea98a39e2d757892a79c78aflorian invalid_character = 1; 7546d9b9b23ea3541501ea98a39e2d757892a79c78aflorian break; 7556d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 7566d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 7576d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 7586d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 7596d9b9b23ea3541501ea98a39e2d757892a79c78aflorian /* OK */ 7606d9b9b23ea3541501ea98a39e2d757892a79c78aflorian UInt abcd = byte1 & 0xf; 7616d9b9b23ea3541501ea98a39e2d757892a79c78aflorian UInt efghij = byte2 & 0x3f; 7626d9b9b23ea3541501ea98a39e2d757892a79c78aflorian UInt klmnop = byte3 & 0x3f; 7636d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 7646d9b9b23ea3541501ea98a39e2d757892a79c78aflorian num_bytes = 2; 7656d9b9b23ea3541501ea98a39e2d757892a79c78aflorian retval = (abcd << 12) | (efghij << 6) | klmnop; 7666d9b9b23ea3541501ea98a39e2d757892a79c78aflorian break; 7676d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 7686d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 7696d9b9b23ea3541501ea98a39e2d757892a79c78aflorian case 4: { 7706d9b9b23ea3541501ea98a39e2d757892a79c78aflorian /* Test validity */ 7716d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if (etf3_and_m3_is_1) { 7726d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if (byte1 == 0xf0) { 7736d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if ((byte2 < 0x90 || byte2 > 0xbf) || 7746d9b9b23ea3541501ea98a39e2d757892a79c78aflorian (byte3 < 0x80 || byte3 > 0xbf) || 7756d9b9b23ea3541501ea98a39e2d757892a79c78aflorian (byte4 < 0x80 || byte4 > 0xbf)) { 7766d9b9b23ea3541501ea98a39e2d757892a79c78aflorian invalid_character = 1; 7776d9b9b23ea3541501ea98a39e2d757892a79c78aflorian break; 7786d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 7796d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 7806d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if (byte1 == 0xf1 || byte1 == 0xf2 || byte1 == 0xf3) { 7816d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if ((byte2 < 0x80 || byte2 > 0xbf) || 7826d9b9b23ea3541501ea98a39e2d757892a79c78aflorian (byte3 < 0x80 || byte3 > 0xbf) || 7836d9b9b23ea3541501ea98a39e2d757892a79c78aflorian (byte4 < 0x80 || byte4 > 0xbf)) { 7846d9b9b23ea3541501ea98a39e2d757892a79c78aflorian invalid_character = 1; 7856d9b9b23ea3541501ea98a39e2d757892a79c78aflorian break; 7866d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 7876d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 7886d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if (byte1 == 0xf4) { 7896d9b9b23ea3541501ea98a39e2d757892a79c78aflorian if ((byte2 < 0x80 || byte2 > 0x8f) || 7906d9b9b23ea3541501ea98a39e2d757892a79c78aflorian (byte3 < 0x80 || byte3 > 0xbf) || 7916d9b9b23ea3541501ea98a39e2d757892a79c78aflorian (byte4 < 0x80 || byte4 > 0xbf)) { 7926d9b9b23ea3541501ea98a39e2d757892a79c78aflorian invalid_character = 1; 7936d9b9b23ea3541501ea98a39e2d757892a79c78aflorian break; 7946d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 7956d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 7966d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 7976d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 7986d9b9b23ea3541501ea98a39e2d757892a79c78aflorian /* OK */ 7996d9b9b23ea3541501ea98a39e2d757892a79c78aflorian UInt uvw = byte1 & 0x7; 8006d9b9b23ea3541501ea98a39e2d757892a79c78aflorian UInt xy = (byte2 >> 4) & 0x3; 8016d9b9b23ea3541501ea98a39e2d757892a79c78aflorian UInt uvwxy = (uvw << 2) | xy; 8026d9b9b23ea3541501ea98a39e2d757892a79c78aflorian UInt efgh = byte2 & 0xf; 8036d9b9b23ea3541501ea98a39e2d757892a79c78aflorian UInt ij = (byte3 >> 4) & 0x3; 8046d9b9b23ea3541501ea98a39e2d757892a79c78aflorian UInt klmn = byte3 & 0xf; 8056d9b9b23ea3541501ea98a39e2d757892a79c78aflorian UInt opqrst = byte4 & 0x3f; 8066d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 8073f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian if (is_cu12) { 8083f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian UInt abcd = (uvwxy - 1) & 0xf; 8093f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian UInt high_surrogate = (0xd8 << 8) | (abcd << 6) | (efgh << 2) | ij; 8103f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian UInt low_surrogate = (0xdc << 8) | (klmn << 6) | opqrst; 8113f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian 8123f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian num_bytes = 4; 8133f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian retval = (high_surrogate << 16) | low_surrogate; 8143f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian } else { 8153f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian num_bytes = 4; 8163f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian retval = 8173f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian (uvwxy << 16) | (efgh << 12) | (ij << 10) | (klmn << 6) | opqrst; 8183f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian } 8196d9b9b23ea3541501ea98a39e2d757892a79c78aflorian break; 8206d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 8216d9b9b23ea3541501ea98a39e2d757892a79c78aflorian } 8226d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 8233f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian if (! is_cu12) num_bytes = 4; // for CU14, by definition 8243f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian 8256d9b9b23ea3541501ea98a39e2d757892a79c78aflorian /* At this point RETVAL contains the converted bytes. 8266d9b9b23ea3541501ea98a39e2d757892a79c78aflorian Build up the final return value. */ 8276d9b9b23ea3541501ea98a39e2d757892a79c78aflorian return (retval << 16) | (num_bytes << 8) | invalid_character; 8286d9b9b23ea3541501ea98a39e2d757892a79c78aflorian} 8296d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 8303f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florianULong 8313f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florians390_do_cu12_helper2(UInt byte1, UInt byte2, UInt byte3, UInt byte4, 8323f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian ULong stuff) 8333f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian{ 8343f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian return s390_do_cu12_cu14_helper2(byte1, byte2, byte3, byte4, stuff, 8353f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian /* is_cu12 = */ 1); 8363f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian} 8373f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian 8383f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florianULong 8393f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florians390_do_cu14_helper2(UInt byte1, UInt byte2, UInt byte3, UInt byte4, 8403f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian ULong stuff) 8413f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian{ 8423f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian return s390_do_cu12_cu14_helper2(byte1, byte2, byte3, byte4, stuff, 8433f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian /* is_cu12 = */ 0); 8443f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian} 8453f8a96a5e5e9baac2ce8eeeb8d10db92e9bd6ae4florian 8466d9b9b23ea3541501ea98a39e2d757892a79c78aflorian 8476d9b9b23ea3541501ea98a39e2d757892a79c78aflorian/*------------------------------------------------------------*/ 848e711c805f1de40b8fafce36d04e589c6a5074e9aflorian/*--- Clean helper for "convert to binary". ---*/ 849e711c805f1de40b8fafce36d04e589c6a5074e9aflorian/*------------------------------------------------------------*/ 850e711c805f1de40b8fafce36d04e589c6a5074e9aflorian#if defined(VGA_s390x) 851e711c805f1de40b8fafce36d04e589c6a5074e9aflorianUInt 852e711c805f1de40b8fafce36d04e589c6a5074e9aflorians390_do_cvb(ULong decimal) 853e711c805f1de40b8fafce36d04e589c6a5074e9aflorian{ 854e711c805f1de40b8fafce36d04e589c6a5074e9aflorian UInt binary; 855e711c805f1de40b8fafce36d04e589c6a5074e9aflorian 856e711c805f1de40b8fafce36d04e589c6a5074e9aflorian __asm__ volatile ( 857e711c805f1de40b8fafce36d04e589c6a5074e9aflorian "cvb %[result],%[input]\n\t" 858e711c805f1de40b8fafce36d04e589c6a5074e9aflorian : [result] "=d"(binary) 859e711c805f1de40b8fafce36d04e589c6a5074e9aflorian : [input] "m"(decimal) 860e711c805f1de40b8fafce36d04e589c6a5074e9aflorian ); 861e711c805f1de40b8fafce36d04e589c6a5074e9aflorian 862e711c805f1de40b8fafce36d04e589c6a5074e9aflorian return binary; 863e711c805f1de40b8fafce36d04e589c6a5074e9aflorian} 864e711c805f1de40b8fafce36d04e589c6a5074e9aflorian 865e711c805f1de40b8fafce36d04e589c6a5074e9aflorian#else 866e711c805f1de40b8fafce36d04e589c6a5074e9aflorianUInt s390_do_cvb(ULong decimal) { return 0; } 867e711c805f1de40b8fafce36d04e589c6a5074e9aflorian#endif 868e711c805f1de40b8fafce36d04e589c6a5074e9aflorian 869e711c805f1de40b8fafce36d04e589c6a5074e9aflorian 870e711c805f1de40b8fafce36d04e589c6a5074e9aflorian/*------------------------------------------------------------*/ 871e711c805f1de40b8fafce36d04e589c6a5074e9aflorian/*--- Clean helper for "convert to decimal". ---*/ 872e711c805f1de40b8fafce36d04e589c6a5074e9aflorian/*------------------------------------------------------------*/ 873e711c805f1de40b8fafce36d04e589c6a5074e9aflorian#if defined(VGA_s390x) 874e711c805f1de40b8fafce36d04e589c6a5074e9aflorianULong 875e711c805f1de40b8fafce36d04e589c6a5074e9aflorians390_do_cvd(ULong binary_in) 876e711c805f1de40b8fafce36d04e589c6a5074e9aflorian{ 877e711c805f1de40b8fafce36d04e589c6a5074e9aflorian UInt binary = binary_in & 0xffffffffULL; 878e711c805f1de40b8fafce36d04e589c6a5074e9aflorian ULong decimal; 879e711c805f1de40b8fafce36d04e589c6a5074e9aflorian 880e711c805f1de40b8fafce36d04e589c6a5074e9aflorian __asm__ volatile ( 881e711c805f1de40b8fafce36d04e589c6a5074e9aflorian "cvd %[input],%[result]\n\t" 882e711c805f1de40b8fafce36d04e589c6a5074e9aflorian : [result] "=m"(decimal) 883e711c805f1de40b8fafce36d04e589c6a5074e9aflorian : [input] "d"(binary) 884e711c805f1de40b8fafce36d04e589c6a5074e9aflorian ); 885e711c805f1de40b8fafce36d04e589c6a5074e9aflorian 886e711c805f1de40b8fafce36d04e589c6a5074e9aflorian return decimal; 887e711c805f1de40b8fafce36d04e589c6a5074e9aflorian} 888e711c805f1de40b8fafce36d04e589c6a5074e9aflorian 889e711c805f1de40b8fafce36d04e589c6a5074e9aflorian#else 890e711c805f1de40b8fafce36d04e589c6a5074e9aflorianULong s390_do_cvd(ULong binary) { return 0; } 891e711c805f1de40b8fafce36d04e589c6a5074e9aflorian#endif 892e711c805f1de40b8fafce36d04e589c6a5074e9aflorian 8938c88cb6ae821021e1e00be18f5a8bea3c557080aflorian/*------------------------------------------------------------*/ 8948c88cb6ae821021e1e00be18f5a8bea3c557080aflorian/*--- Clean helper for "Extract cache attribute". ---*/ 8958c88cb6ae821021e1e00be18f5a8bea3c557080aflorian/*------------------------------------------------------------*/ 8968c88cb6ae821021e1e00be18f5a8bea3c557080aflorian#if defined(VGA_s390x) 8978c88cb6ae821021e1e00be18f5a8bea3c557080aflorianULong 8988c88cb6ae821021e1e00be18f5a8bea3c557080aflorians390_do_ecag(ULong op2addr) 8998c88cb6ae821021e1e00be18f5a8bea3c557080aflorian{ 9008c88cb6ae821021e1e00be18f5a8bea3c557080aflorian ULong result; 9018c88cb6ae821021e1e00be18f5a8bea3c557080aflorian 9028c88cb6ae821021e1e00be18f5a8bea3c557080aflorian __asm__ volatile(".insn rsy,0xEB000000004C,%[out],0,0(%[in])\n\t" 9038c88cb6ae821021e1e00be18f5a8bea3c557080aflorian : [out] "=d"(result) 9048c88cb6ae821021e1e00be18f5a8bea3c557080aflorian : [in] "d"(op2addr)); 9058c88cb6ae821021e1e00be18f5a8bea3c557080aflorian return result; 9068c88cb6ae821021e1e00be18f5a8bea3c557080aflorian} 9078c88cb6ae821021e1e00be18f5a8bea3c557080aflorian 9088c88cb6ae821021e1e00be18f5a8bea3c557080aflorian#else 9098c88cb6ae821021e1e00be18f5a8bea3c557080aflorianULong s390_do_ecag(ULong op2addr) { return 0; } 9108c88cb6ae821021e1e00be18f5a8bea3c557080aflorian#endif 911e711c805f1de40b8fafce36d04e589c6a5074e9aflorian 912933065d4f3548466da4666c5cfda7e5eaff93759florian/*------------------------------------------------------------*/ 91378d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian/*--- Clean helper for "Perform Floating Point Operation". ---*/ 91478d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian/*------------------------------------------------------------*/ 91578d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian#if defined(VGA_s390x) 91678d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florianUInt 91778d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florians390_do_pfpo(UInt gpr0) 91878d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian{ 91978d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian UChar rm; 92078d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian UChar op1_ty, op2_ty; 92178d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian 92278d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian rm = gpr0 & 0xf; 92378d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian if (rm > 1 && rm < 8) 92478d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian return EmFail_S390X_invalid_PFPO_rounding_mode; 92578d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian 92678d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian op1_ty = (gpr0 >> 16) & 0xff; // gpr0[40:47] 92778d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian op2_ty = (gpr0 >> 8) & 0xff; // gpr0[48:55] 92878d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian /* Operand type must be BFP 32, 64, 128 or DFP 32, 64, 128 92978d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian which correspond to 0x5, 0x6, 0x7, 0x8, 0x9, 0xa respectively. 93078d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian Any other operand type value is unsupported */ 93178d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian if ((op1_ty == op2_ty) || 93278d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian (op1_ty < 0x5 || op1_ty > 0xa) || 93378d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian (op2_ty < 0x5 || op2_ty > 0xa)) 93478d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian return EmFail_S390X_invalid_PFPO_function; 93578d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian 93678d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian return EmNote_NONE; 93778d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian} 93878d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian#else 93978d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florianUInt s390_do_pfpo(UInt gpr0) { return 0; } 94078d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian#endif 94178d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian 94278d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian/*------------------------------------------------------------*/ 9432019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*--- Helper for condition code. ---*/ 9442019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*------------------------------------------------------------*/ 9452019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 94683f60b5fac7ad065935f3c2fcf7b1454d552d6e0florian/* Convert an IRRoundingMode value to s390_bfp_round_t */ 9473d80fade93ec633f3ad30f871d1a1306f75823c6florian#if defined(VGA_s390x) 948125e20dc4036944b19bed3e98a15d05cce8c29f6florianstatic s390_bfp_round_t 94919e0077d31fe17496eeb76cd008507d1a8f75908floriandecode_bfp_rounding_mode(UInt irrm) 95019e0077d31fe17496eeb76cd008507d1a8f75908florian{ 95119e0077d31fe17496eeb76cd008507d1a8f75908florian switch (irrm) { 952125e20dc4036944b19bed3e98a15d05cce8c29f6florian case Irrm_NEAREST: return S390_BFP_ROUND_NEAREST_EVEN; 953125e20dc4036944b19bed3e98a15d05cce8c29f6florian case Irrm_NegINF: return S390_BFP_ROUND_NEGINF; 954125e20dc4036944b19bed3e98a15d05cce8c29f6florian case Irrm_PosINF: return S390_BFP_ROUND_POSINF; 955125e20dc4036944b19bed3e98a15d05cce8c29f6florian case Irrm_ZERO: return S390_BFP_ROUND_ZERO; 95619e0077d31fe17496eeb76cd008507d1a8f75908florian } 95719e0077d31fe17496eeb76cd008507d1a8f75908florian vpanic("decode_bfp_rounding_mode"); 95819e0077d31fe17496eeb76cd008507d1a8f75908florian} 9593d80fade93ec633f3ad30f871d1a1306f75823c6florian#endif 96019e0077d31fe17496eeb76cd008507d1a8f75908florian 96119e0077d31fe17496eeb76cd008507d1a8f75908florian 9622019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#define S390_CC_FOR_BINARY(opcode,cc_dep1,cc_dep2) \ 9632019a976f07ff418dde2dfc7cc74667ef66d7764sewardj({ \ 9642019a976f07ff418dde2dfc7cc74667ef66d7764sewardj __asm__ volatile ( \ 9652019a976f07ff418dde2dfc7cc74667ef66d7764sewardj opcode " %[op1],%[op2]\n\t" \ 9662019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ipm %[psw]\n\t" : [psw] "=d"(psw), [op1] "+d"(cc_dep1) \ 9672019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : [op2] "d"(cc_dep2) \ 9682019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : "cc");\ 9692019a976f07ff418dde2dfc7cc74667ef66d7764sewardj psw >> 28; /* cc */ \ 9702019a976f07ff418dde2dfc7cc74667ef66d7764sewardj}) 9712019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 9722019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#define S390_CC_FOR_TERNARY_SUBB(opcode,cc_dep1,cc_dep2,cc_ndep) \ 9732019a976f07ff418dde2dfc7cc74667ef66d7764sewardj({ \ 9742019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Recover the original DEP2 value. See comment near s390_cc_thunk_put3 \ 9752019a976f07ff418dde2dfc7cc74667ef66d7764sewardj for rationale. */ \ 9762019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc_dep2 = cc_dep2 ^ cc_ndep; \ 9772019a976f07ff418dde2dfc7cc74667ef66d7764sewardj __asm__ volatile ( \ 9782019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "lghi 0,1\n\t" \ 9792019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "sr 0,%[op3]\n\t" /* borrow to cc */ \ 9802019a976f07ff418dde2dfc7cc74667ef66d7764sewardj opcode " %[op1],%[op2]\n\t" /* then redo the op */\ 9812019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ipm %[psw]\n\t" : [psw] "=d"(psw), [op1] "+&d"(cc_dep1) \ 9822019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : [op2] "d"(cc_dep2), [op3] "d"(cc_ndep) \ 9832019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : "0", "cc");\ 9842019a976f07ff418dde2dfc7cc74667ef66d7764sewardj psw >> 28; /* cc */ \ 9852019a976f07ff418dde2dfc7cc74667ef66d7764sewardj}) 9862019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 9872019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#define S390_CC_FOR_TERNARY_ADDC(opcode,cc_dep1,cc_dep2,cc_ndep) \ 9882019a976f07ff418dde2dfc7cc74667ef66d7764sewardj({ \ 9892019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Recover the original DEP2 value. See comment near s390_cc_thunk_put3 \ 9902019a976f07ff418dde2dfc7cc74667ef66d7764sewardj for rationale. */ \ 9912019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc_dep2 = cc_dep2 ^ cc_ndep; \ 9922019a976f07ff418dde2dfc7cc74667ef66d7764sewardj __asm__ volatile ( \ 9932019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "lgfr 0,%[op3]\n\t" /* first load cc_ndep */ \ 9942019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "aghi 0,0\n\t" /* and convert it into a cc */ \ 9952019a976f07ff418dde2dfc7cc74667ef66d7764sewardj opcode " %[op1],%[op2]\n\t" /* then redo the op */\ 9962019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ipm %[psw]\n\t" : [psw] "=d"(psw), [op1] "+&d"(cc_dep1) \ 9972019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : [op2] "d"(cc_dep2), [op3] "d"(cc_ndep) \ 9982019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : "0", "cc");\ 9992019a976f07ff418dde2dfc7cc74667ef66d7764sewardj psw >> 28; /* cc */ \ 10002019a976f07ff418dde2dfc7cc74667ef66d7764sewardj}) 10012019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 10022019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 10032019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#define S390_CC_FOR_BFP_RESULT(opcode,cc_dep1) \ 10042019a976f07ff418dde2dfc7cc74667ef66d7764sewardj({ \ 10052019a976f07ff418dde2dfc7cc74667ef66d7764sewardj __asm__ volatile ( \ 10062019a976f07ff418dde2dfc7cc74667ef66d7764sewardj opcode " 0,%[op]\n\t" \ 10072019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ipm %[psw]\n\t" : [psw] "=d"(psw) \ 10082019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : [op] "f"(cc_dep1) \ 10092019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : "cc", "f0");\ 10102019a976f07ff418dde2dfc7cc74667ef66d7764sewardj psw >> 28; /* cc */ \ 10112019a976f07ff418dde2dfc7cc74667ef66d7764sewardj}) 10122019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 10132019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#define S390_CC_FOR_BFP128_RESULT(hi,lo) \ 10142019a976f07ff418dde2dfc7cc74667ef66d7764sewardj({ \ 10152019a976f07ff418dde2dfc7cc74667ef66d7764sewardj __asm__ volatile ( \ 10162019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ldr 4,%[high]\n\t" \ 10172019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ldr 6,%[low]\n\t" \ 10182019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ltxbr 0,4\n\t" \ 10192019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ipm %[psw]\n\t" : [psw] "=d"(psw) \ 10202019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : [high] "f"(hi), [low] "f"(lo) \ 10212019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : "cc", "f0", "f2", "f4", "f6");\ 10222019a976f07ff418dde2dfc7cc74667ef66d7764sewardj psw >> 28; /* cc */ \ 10232019a976f07ff418dde2dfc7cc74667ef66d7764sewardj}) 10242019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 102519e0077d31fe17496eeb76cd008507d1a8f75908florian#define S390_CC_FOR_BFP_CONVERT_AUX(opcode,cc_dep1,rounding_mode) \ 10262019a976f07ff418dde2dfc7cc74667ef66d7764sewardj({ \ 10272019a976f07ff418dde2dfc7cc74667ef66d7764sewardj __asm__ volatile ( \ 102819e0077d31fe17496eeb76cd008507d1a8f75908florian opcode " 0," #rounding_mode ",%[op]\n\t" \ 10292019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ipm %[psw]\n\t" : [psw] "=d"(psw) \ 10302019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : [op] "f"(cc_dep1) \ 10312019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : "cc", "r0");\ 10322019a976f07ff418dde2dfc7cc74667ef66d7764sewardj psw >> 28; /* cc */ \ 10332019a976f07ff418dde2dfc7cc74667ef66d7764sewardj}) 10342019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 103519e0077d31fe17496eeb76cd008507d1a8f75908florian#define S390_CC_FOR_BFP_CONVERT(opcode,cc_dep1,cc_dep2) \ 103619e0077d31fe17496eeb76cd008507d1a8f75908florian({ \ 103719e0077d31fe17496eeb76cd008507d1a8f75908florian UInt cc; \ 103819e0077d31fe17496eeb76cd008507d1a8f75908florian switch (decode_bfp_rounding_mode(cc_dep2)) { \ 1039125e20dc4036944b19bed3e98a15d05cce8c29f6florian case S390_BFP_ROUND_NEAREST_EVEN: \ 104019e0077d31fe17496eeb76cd008507d1a8f75908florian cc = S390_CC_FOR_BFP_CONVERT_AUX(opcode,cc_dep1,4); \ 104119e0077d31fe17496eeb76cd008507d1a8f75908florian break; \ 1042125e20dc4036944b19bed3e98a15d05cce8c29f6florian case S390_BFP_ROUND_ZERO: \ 104319e0077d31fe17496eeb76cd008507d1a8f75908florian cc = S390_CC_FOR_BFP_CONVERT_AUX(opcode,cc_dep1,5); \ 104419e0077d31fe17496eeb76cd008507d1a8f75908florian break; \ 1045125e20dc4036944b19bed3e98a15d05cce8c29f6florian case S390_BFP_ROUND_POSINF: \ 104619e0077d31fe17496eeb76cd008507d1a8f75908florian cc = S390_CC_FOR_BFP_CONVERT_AUX(opcode,cc_dep1,6); \ 104719e0077d31fe17496eeb76cd008507d1a8f75908florian break; \ 1048125e20dc4036944b19bed3e98a15d05cce8c29f6florian case S390_BFP_ROUND_NEGINF: \ 104919e0077d31fe17496eeb76cd008507d1a8f75908florian cc = S390_CC_FOR_BFP_CONVERT_AUX(opcode,cc_dep1,7); \ 105019e0077d31fe17496eeb76cd008507d1a8f75908florian break; \ 105119e0077d31fe17496eeb76cd008507d1a8f75908florian default: \ 1052125e20dc4036944b19bed3e98a15d05cce8c29f6florian vpanic("unexpected bfp rounding mode"); \ 105319e0077d31fe17496eeb76cd008507d1a8f75908florian } \ 105419e0077d31fe17496eeb76cd008507d1a8f75908florian cc; \ 105519e0077d31fe17496eeb76cd008507d1a8f75908florian}) 105619e0077d31fe17496eeb76cd008507d1a8f75908florian 105719e0077d31fe17496eeb76cd008507d1a8f75908florian#define S390_CC_FOR_BFP_UCONVERT_AUX(opcode,cc_dep1,rounding_mode) \ 10581c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian({ \ 10591c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian __asm__ volatile ( \ 106019e0077d31fe17496eeb76cd008507d1a8f75908florian opcode ",0,%[op]," #rounding_mode ",0\n\t" \ 10611c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian "ipm %[psw]\n\t" : [psw] "=d"(psw) \ 10621c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian : [op] "f"(cc_dep1) \ 10631c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian : "cc", "r0");\ 10641c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian psw >> 28; /* cc */ \ 10651c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian}) 10661c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian 106719e0077d31fe17496eeb76cd008507d1a8f75908florian#define S390_CC_FOR_BFP_UCONVERT(opcode,cc_dep1,cc_dep2) \ 106819e0077d31fe17496eeb76cd008507d1a8f75908florian({ \ 106919e0077d31fe17496eeb76cd008507d1a8f75908florian UInt cc; \ 107019e0077d31fe17496eeb76cd008507d1a8f75908florian switch (decode_bfp_rounding_mode(cc_dep2)) { \ 1071125e20dc4036944b19bed3e98a15d05cce8c29f6florian case S390_BFP_ROUND_NEAREST_EVEN: \ 107219e0077d31fe17496eeb76cd008507d1a8f75908florian cc = S390_CC_FOR_BFP_UCONVERT_AUX(opcode,cc_dep1,4); \ 107319e0077d31fe17496eeb76cd008507d1a8f75908florian break; \ 1074125e20dc4036944b19bed3e98a15d05cce8c29f6florian case S390_BFP_ROUND_ZERO: \ 107519e0077d31fe17496eeb76cd008507d1a8f75908florian cc = S390_CC_FOR_BFP_UCONVERT_AUX(opcode,cc_dep1,5); \ 107619e0077d31fe17496eeb76cd008507d1a8f75908florian break; \ 1077125e20dc4036944b19bed3e98a15d05cce8c29f6florian case S390_BFP_ROUND_POSINF: \ 107819e0077d31fe17496eeb76cd008507d1a8f75908florian cc = S390_CC_FOR_BFP_UCONVERT_AUX(opcode,cc_dep1,6); \ 107919e0077d31fe17496eeb76cd008507d1a8f75908florian break; \ 1080125e20dc4036944b19bed3e98a15d05cce8c29f6florian case S390_BFP_ROUND_NEGINF: \ 108119e0077d31fe17496eeb76cd008507d1a8f75908florian cc = S390_CC_FOR_BFP_UCONVERT_AUX(opcode,cc_dep1,7); \ 108219e0077d31fe17496eeb76cd008507d1a8f75908florian break; \ 108319e0077d31fe17496eeb76cd008507d1a8f75908florian default: \ 1084125e20dc4036944b19bed3e98a15d05cce8c29f6florian vpanic("unexpected bfp rounding mode"); \ 108519e0077d31fe17496eeb76cd008507d1a8f75908florian } \ 108619e0077d31fe17496eeb76cd008507d1a8f75908florian cc; \ 108719e0077d31fe17496eeb76cd008507d1a8f75908florian}) 108819e0077d31fe17496eeb76cd008507d1a8f75908florian 108919e0077d31fe17496eeb76cd008507d1a8f75908florian#define S390_CC_FOR_BFP128_CONVERT_AUX(opcode,hi,lo,rounding_mode) \ 10902019a976f07ff418dde2dfc7cc74667ef66d7764sewardj({ \ 10912019a976f07ff418dde2dfc7cc74667ef66d7764sewardj __asm__ volatile ( \ 10922019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ldr 4,%[high]\n\t" \ 10932019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ldr 6,%[low]\n\t" \ 109419e0077d31fe17496eeb76cd008507d1a8f75908florian opcode " 0," #rounding_mode ",4\n\t" \ 10952019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ipm %[psw]\n\t" : [psw] "=d"(psw) \ 10962019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : [high] "f"(hi), [low] "f"(lo) \ 10972019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : "cc", "r0", "f4", "f6");\ 10982019a976f07ff418dde2dfc7cc74667ef66d7764sewardj psw >> 28; /* cc */ \ 10992019a976f07ff418dde2dfc7cc74667ef66d7764sewardj}) 11002019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 110119e0077d31fe17496eeb76cd008507d1a8f75908florian#define S390_CC_FOR_BFP128_CONVERT(opcode,cc_dep1,cc_dep2,cc_ndep) \ 110219e0077d31fe17496eeb76cd008507d1a8f75908florian({ \ 110319e0077d31fe17496eeb76cd008507d1a8f75908florian UInt cc; \ 110419e0077d31fe17496eeb76cd008507d1a8f75908florian /* Recover the original DEP2 value. See comment near \ 110519e0077d31fe17496eeb76cd008507d1a8f75908florian s390_cc_thunk_put3 for rationale. */ \ 110619e0077d31fe17496eeb76cd008507d1a8f75908florian cc_dep2 = cc_dep2 ^ cc_ndep; \ 110719e0077d31fe17496eeb76cd008507d1a8f75908florian switch (decode_bfp_rounding_mode(cc_ndep)) { \ 1108125e20dc4036944b19bed3e98a15d05cce8c29f6florian case S390_BFP_ROUND_NEAREST_EVEN: \ 110919e0077d31fe17496eeb76cd008507d1a8f75908florian cc = S390_CC_FOR_BFP128_CONVERT_AUX(opcode,cc_dep1,cc_dep2,4); \ 111019e0077d31fe17496eeb76cd008507d1a8f75908florian break; \ 1111125e20dc4036944b19bed3e98a15d05cce8c29f6florian case S390_BFP_ROUND_ZERO: \ 111219e0077d31fe17496eeb76cd008507d1a8f75908florian cc = S390_CC_FOR_BFP128_CONVERT_AUX(opcode,cc_dep1,cc_dep2,5); \ 111319e0077d31fe17496eeb76cd008507d1a8f75908florian break; \ 1114125e20dc4036944b19bed3e98a15d05cce8c29f6florian case S390_BFP_ROUND_POSINF: \ 111519e0077d31fe17496eeb76cd008507d1a8f75908florian cc = S390_CC_FOR_BFP128_CONVERT_AUX(opcode,cc_dep1,cc_dep2,6); \ 111619e0077d31fe17496eeb76cd008507d1a8f75908florian break; \ 1117125e20dc4036944b19bed3e98a15d05cce8c29f6florian case S390_BFP_ROUND_NEGINF: \ 111819e0077d31fe17496eeb76cd008507d1a8f75908florian cc = S390_CC_FOR_BFP128_CONVERT_AUX(opcode,cc_dep1,cc_dep2,7); \ 111919e0077d31fe17496eeb76cd008507d1a8f75908florian break; \ 112019e0077d31fe17496eeb76cd008507d1a8f75908florian default: \ 1121125e20dc4036944b19bed3e98a15d05cce8c29f6florian vpanic("unexpected bfp rounding mode"); \ 112219e0077d31fe17496eeb76cd008507d1a8f75908florian } \ 112319e0077d31fe17496eeb76cd008507d1a8f75908florian cc; \ 112419e0077d31fe17496eeb76cd008507d1a8f75908florian}) 112519e0077d31fe17496eeb76cd008507d1a8f75908florian 112619e0077d31fe17496eeb76cd008507d1a8f75908florian#define S390_CC_FOR_BFP128_UCONVERT_AUX(opcode,hi,lo,rounding_mode) \ 11271c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian({ \ 11281c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian __asm__ volatile ( \ 11291c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian "ldr 4,%[high]\n\t" \ 11301c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian "ldr 6,%[low]\n\t" \ 113119e0077d31fe17496eeb76cd008507d1a8f75908florian opcode ",0,4," #rounding_mode ",0\n\t" \ 11321c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian "ipm %[psw]\n\t" : [psw] "=d"(psw) \ 11331c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian : [high] "f"(hi), [low] "f"(lo) \ 11341c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian : "cc", "r0", "f4", "f6");\ 11351c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian psw >> 28; /* cc */ \ 11361c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian}) 11371c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian 113819e0077d31fe17496eeb76cd008507d1a8f75908florian#define S390_CC_FOR_BFP128_UCONVERT(opcode,cc_dep1,cc_dep2,cc_ndep) \ 113919e0077d31fe17496eeb76cd008507d1a8f75908florian({ \ 114019e0077d31fe17496eeb76cd008507d1a8f75908florian UInt cc; \ 114119e0077d31fe17496eeb76cd008507d1a8f75908florian /* Recover the original DEP2 value. See comment near \ 114219e0077d31fe17496eeb76cd008507d1a8f75908florian s390_cc_thunk_put3 for rationale. */ \ 114319e0077d31fe17496eeb76cd008507d1a8f75908florian cc_dep2 = cc_dep2 ^ cc_ndep; \ 114419e0077d31fe17496eeb76cd008507d1a8f75908florian switch (decode_bfp_rounding_mode(cc_ndep)) { \ 1145125e20dc4036944b19bed3e98a15d05cce8c29f6florian case S390_BFP_ROUND_NEAREST_EVEN: \ 114619e0077d31fe17496eeb76cd008507d1a8f75908florian cc = S390_CC_FOR_BFP128_UCONVERT_AUX(opcode,cc_dep1,cc_dep2,4); \ 114719e0077d31fe17496eeb76cd008507d1a8f75908florian break; \ 1148125e20dc4036944b19bed3e98a15d05cce8c29f6florian case S390_BFP_ROUND_ZERO: \ 114919e0077d31fe17496eeb76cd008507d1a8f75908florian cc = S390_CC_FOR_BFP128_UCONVERT_AUX(opcode,cc_dep1,cc_dep2,5); \ 115019e0077d31fe17496eeb76cd008507d1a8f75908florian break; \ 1151125e20dc4036944b19bed3e98a15d05cce8c29f6florian case S390_BFP_ROUND_POSINF: \ 115219e0077d31fe17496eeb76cd008507d1a8f75908florian cc = S390_CC_FOR_BFP128_UCONVERT_AUX(opcode,cc_dep1,cc_dep2,6); \ 115319e0077d31fe17496eeb76cd008507d1a8f75908florian break; \ 1154125e20dc4036944b19bed3e98a15d05cce8c29f6florian case S390_BFP_ROUND_NEGINF: \ 115519e0077d31fe17496eeb76cd008507d1a8f75908florian cc = S390_CC_FOR_BFP128_UCONVERT_AUX(opcode,cc_dep1,cc_dep2,7); \ 115619e0077d31fe17496eeb76cd008507d1a8f75908florian break; \ 115719e0077d31fe17496eeb76cd008507d1a8f75908florian default: \ 1158125e20dc4036944b19bed3e98a15d05cce8c29f6florian vpanic("unexpected bfp rounding mode"); \ 115919e0077d31fe17496eeb76cd008507d1a8f75908florian } \ 116019e0077d31fe17496eeb76cd008507d1a8f75908florian cc; \ 116119e0077d31fe17496eeb76cd008507d1a8f75908florian}) 116219e0077d31fe17496eeb76cd008507d1a8f75908florian 11632019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#define S390_CC_FOR_BFP_TDC(opcode,cc_dep1,cc_dep2) \ 11642019a976f07ff418dde2dfc7cc74667ef66d7764sewardj({ \ 11652019a976f07ff418dde2dfc7cc74667ef66d7764sewardj __asm__ volatile ( \ 11662019a976f07ff418dde2dfc7cc74667ef66d7764sewardj opcode " %[value],0(%[class])\n\t" \ 11672019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ipm %[psw]\n\t" : [psw] "=d"(psw) \ 11682019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : [value] "f"(cc_dep1), \ 11692019a976f07ff418dde2dfc7cc74667ef66d7764sewardj [class] "a"(cc_dep2) \ 11702019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : "cc");\ 11712019a976f07ff418dde2dfc7cc74667ef66d7764sewardj psw >> 28; /* cc */ \ 11722019a976f07ff418dde2dfc7cc74667ef66d7764sewardj}) 11732019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 11742019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#define S390_CC_FOR_BFP128_TDC(cc_dep1,cc_dep2,cc_ndep) \ 11752019a976f07ff418dde2dfc7cc74667ef66d7764sewardj({ \ 1176cf1527c8f8a8a647cae5ef21b6b126db9b81f622florian /* Recover the original DEP2 value. See comment near \ 1177cf1527c8f8a8a647cae5ef21b6b126db9b81f622florian s390_cc_thunk_put1f128Z for rationale. */ \ 11782019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc_dep2 = cc_dep2 ^ cc_ndep; \ 11792019a976f07ff418dde2dfc7cc74667ef66d7764sewardj __asm__ volatile ( \ 11802019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ldr 4,%[high]\n\t" \ 11812019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ldr 6,%[low]\n\t" \ 11822019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "tcxb 4,0(%[class])\n\t" \ 11832019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ipm %[psw]\n\t" : [psw] "=d"(psw) \ 11842019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : [high] "f"(cc_dep1), [low] "f"(cc_dep2), \ 11852019a976f07ff418dde2dfc7cc74667ef66d7764sewardj [class] "a"(cc_ndep) \ 11862019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : "cc", "f4", "f6");\ 11872019a976f07ff418dde2dfc7cc74667ef66d7764sewardj psw >> 28; /* cc */ \ 11882019a976f07ff418dde2dfc7cc74667ef66d7764sewardj}) 11892019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 119079e5a4845df6d09250b142c4e160a95cf7688fc8florian/* Convert an IRRoundingMode value to s390_dfp_round_t */ 11915f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian#if defined(VGA_s390x) 11925f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florianstatic s390_dfp_round_t 11935f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3floriandecode_dfp_rounding_mode(UInt irrm) 11945f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian{ 11955f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian switch (irrm) { 119679e5a4845df6d09250b142c4e160a95cf7688fc8florian case Irrm_NEAREST: 11975f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian return S390_DFP_ROUND_NEAREST_EVEN_4; 119879e5a4845df6d09250b142c4e160a95cf7688fc8florian case Irrm_NegINF: 11995f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian return S390_DFP_ROUND_NEGINF_7; 120079e5a4845df6d09250b142c4e160a95cf7688fc8florian case Irrm_PosINF: 12015f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian return S390_DFP_ROUND_POSINF_6; 120279e5a4845df6d09250b142c4e160a95cf7688fc8florian case Irrm_ZERO: 12035f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian return S390_DFP_ROUND_ZERO_5; 120479e5a4845df6d09250b142c4e160a95cf7688fc8florian case Irrm_NEAREST_TIE_AWAY_0: 12055f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian return S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1; 120679e5a4845df6d09250b142c4e160a95cf7688fc8florian case Irrm_PREPARE_SHORTER: 12075f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian return S390_DFP_ROUND_PREPARE_SHORT_3; 120879e5a4845df6d09250b142c4e160a95cf7688fc8florian case Irrm_AWAY_FROM_ZERO: 12095f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian return S390_DFP_ROUND_AWAY_0; 121079e5a4845df6d09250b142c4e160a95cf7688fc8florian case Irrm_NEAREST_TIE_TOWARD_0: 12115f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian return S390_DFP_ROUND_NEAREST_TIE_TOWARD_0; 12125f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian } 12135f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian vpanic("decode_dfp_rounding_mode"); 12145f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian} 12155f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian#endif 12165f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian 12171239020c948a6e20faaa8d0fa5dea44302e18f8aflorian#define S390_CC_FOR_DFP_RESULT(cc_dep1) \ 12181239020c948a6e20faaa8d0fa5dea44302e18f8aflorian({ \ 12191239020c948a6e20faaa8d0fa5dea44302e18f8aflorian __asm__ volatile ( \ 12201239020c948a6e20faaa8d0fa5dea44302e18f8aflorian ".insn rre, 0xb3d60000,0,%[op]\n\t" /* LTDTR */ \ 12211239020c948a6e20faaa8d0fa5dea44302e18f8aflorian "ipm %[psw]\n\t" : [psw] "=d"(psw) \ 12221239020c948a6e20faaa8d0fa5dea44302e18f8aflorian : [op] "f"(cc_dep1) \ 12231239020c948a6e20faaa8d0fa5dea44302e18f8aflorian : "cc", "f0"); \ 12241239020c948a6e20faaa8d0fa5dea44302e18f8aflorian psw >> 28; /* cc */ \ 12251239020c948a6e20faaa8d0fa5dea44302e18f8aflorian}) 12261239020c948a6e20faaa8d0fa5dea44302e18f8aflorian 1227e38f641461120ea338069a3f45820168959968abflorian#define S390_CC_FOR_DFP128_RESULT(hi,lo) \ 1228e38f641461120ea338069a3f45820168959968abflorian({ \ 1229e38f641461120ea338069a3f45820168959968abflorian __asm__ volatile ( \ 1230cf1527c8f8a8a647cae5ef21b6b126db9b81f622florian "ldr 4,%[high]\n\t" \ 1231cf1527c8f8a8a647cae5ef21b6b126db9b81f622florian "ldr 6,%[low]\n\t" \ 1232cf1527c8f8a8a647cae5ef21b6b126db9b81f622florian ".insn rre, 0xb3de0000,0,4\n\t" /* LTXTR */ \ 1233cf1527c8f8a8a647cae5ef21b6b126db9b81f622florian "ipm %[psw]\n\t" : [psw] "=d"(psw) \ 1234cf1527c8f8a8a647cae5ef21b6b126db9b81f622florian : [high] "f"(hi), [low] "f"(lo) \ 1235cf1527c8f8a8a647cae5ef21b6b126db9b81f622florian : "cc", "f0", "f2", "f4", "f6"); \ 1236e38f641461120ea338069a3f45820168959968abflorian psw >> 28; /* cc */ \ 1237e38f641461120ea338069a3f45820168959968abflorian}) 1238e38f641461120ea338069a3f45820168959968abflorian 1239ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian#define S390_CC_FOR_DFP_TD(opcode,cc_dep1,cc_dep2) \ 1240ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian({ \ 1241ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian __asm__ volatile ( \ 1242ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian opcode ",%[value],0(%[class])\n\t" \ 1243ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian "ipm %[psw]\n\t" : [psw] "=d"(psw) \ 1244ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian : [value] "f"(cc_dep1), \ 1245ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian [class] "a"(cc_dep2) \ 1246ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian : "cc"); \ 1247ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian psw >> 28; /* cc */ \ 1248ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian}) 1249ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian 1250ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian#define S390_CC_FOR_DFP128_TD(opcode,cc_dep1,cc_dep2,cc_ndep) \ 1251ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian({ \ 1252ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian /* Recover the original DEP2 value. See comment near \ 1253ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian s390_cc_thunk_put1d128Z for rationale. */ \ 1254ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian cc_dep2 = cc_dep2 ^ cc_ndep; \ 1255ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian __asm__ volatile ( \ 1256ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian "ldr 4,%[high]\n\t" \ 1257ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian "ldr 6,%[low]\n\t" \ 1258ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian opcode ",4,0(%[class])\n\t" \ 1259ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian "ipm %[psw]\n\t" : [psw] "=d"(psw) \ 1260ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian : [high] "f"(cc_dep1), [low] "f"(cc_dep2), \ 1261ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian [class] "a"(cc_ndep) \ 1262ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian : "cc", "f4", "f6"); \ 1263ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian psw >> 28; /* cc */ \ 1264ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian}) 1265ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian 12665f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian#define S390_CC_FOR_DFP_CONVERT_AUX(opcode,cc_dep1,rounding_mode) \ 12675f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian ({ \ 12685f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian __asm__ volatile ( \ 12695f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian opcode ",0,%[op]," #rounding_mode ",0\n\t" \ 12705f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian "ipm %[psw]\n\t" : [psw] "=d"(psw) \ 12715f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian : [op] "f"(cc_dep1) \ 12725f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian : "cc", "r0"); \ 12735f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian psw >> 28; /* cc */ \ 12745f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian }) 12755f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian 12765f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian#define S390_CC_FOR_DFP_CONVERT(opcode,cc_dep1,cc_dep2) \ 12775f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian ({ \ 12785f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian UInt cc; \ 12795f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian switch (decode_dfp_rounding_mode(cc_dep2)) { \ 12805f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1: \ 12815f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12: \ 12825f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP_CONVERT_AUX(opcode,cc_dep1,1); \ 12835f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 12845f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_PREPARE_SHORT_3: \ 12855f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_PREPARE_SHORT_15: \ 12865f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP_CONVERT_AUX(opcode,cc_dep1,3); \ 12875f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 12885f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_EVEN_4: \ 12895f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_EVEN_8: \ 12905f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP_CONVERT_AUX(opcode,cc_dep1,4); \ 12915f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 12925f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_ZERO_5: \ 12935f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_ZERO_9: \ 12945f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP_CONVERT_AUX(opcode,cc_dep1,5); \ 12955f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 12965f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_POSINF_6: \ 12975f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_POSINF_10: \ 12985f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP_CONVERT_AUX(opcode,cc_dep1,6); \ 12995f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 13005f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEGINF_7: \ 13015f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEGINF_11: \ 13025f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP_CONVERT_AUX(opcode,cc_dep1,7); \ 13035f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 13045f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_TIE_TOWARD_0: \ 13055f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP_CONVERT_AUX(opcode,cc_dep1,13); \ 13065f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 13075f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_AWAY_0: \ 13085f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP_CONVERT_AUX(opcode,cc_dep1,14); \ 13095f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 13105f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian default: \ 13115f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian vpanic("unexpected dfp rounding mode"); \ 13125f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian } \ 13135f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc; \ 13145f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian }) 13155f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian 13165f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian#define S390_CC_FOR_DFP_UCONVERT_AUX(opcode,cc_dep1,rounding_mode) \ 13175f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian ({ \ 13185f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian __asm__ volatile ( \ 13195f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian opcode ",0,%[op]," #rounding_mode ",0\n\t" \ 13205f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian "ipm %[psw]\n\t" : [psw] "=d"(psw) \ 13215f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian : [op] "f"(cc_dep1) \ 13225f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian : "cc", "r0"); \ 13235f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian psw >> 28; /* cc */ \ 13245f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian }) 13255f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian 13265f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian#define S390_CC_FOR_DFP_UCONVERT(opcode,cc_dep1,cc_dep2) \ 13275f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian ({ \ 13285f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian UInt cc; \ 13295f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian switch (decode_dfp_rounding_mode(cc_dep2)) { \ 13305f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1: \ 13315f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12: \ 13325f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP_UCONVERT_AUX(opcode,cc_dep1,1); \ 13335f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 13345f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_PREPARE_SHORT_3: \ 13355f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_PREPARE_SHORT_15: \ 13365f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP_UCONVERT_AUX(opcode,cc_dep1,3); \ 13375f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 13385f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_EVEN_4: \ 13395f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_EVEN_8: \ 13405f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP_UCONVERT_AUX(opcode,cc_dep1,4); \ 13415f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 13425f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_ZERO_5: \ 13435f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_ZERO_9: \ 13445f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP_UCONVERT_AUX(opcode,cc_dep1,5); \ 13455f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 13465f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_POSINF_6: \ 13475f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_POSINF_10: \ 13485f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP_UCONVERT_AUX(opcode,cc_dep1,6); \ 13495f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 13505f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEGINF_7: \ 13515f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEGINF_11: \ 13525f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP_UCONVERT_AUX(opcode,cc_dep1,7); \ 13535f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 13545f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_TIE_TOWARD_0: \ 13555f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP_UCONVERT_AUX(opcode,cc_dep1,13); \ 13565f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 13575f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_AWAY_0: \ 13585f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP_UCONVERT_AUX(opcode,cc_dep1,14); \ 13595f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 13605f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian default: \ 13615f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian vpanic("unexpected dfp rounding mode"); \ 13625f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian } \ 13635f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc; \ 13645f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian }) 13655f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian 13665f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian#define S390_CC_FOR_DFP128_CONVERT_AUX(opcode,hi,lo,rounding_mode) \ 13675f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian ({ \ 13685f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian __asm__ volatile ( \ 13695f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian "ldr 4,%[high]\n\t" \ 13705f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian "ldr 6,%[low]\n\t" \ 13715f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian opcode ",0,4," #rounding_mode ",0\n\t" \ 13725f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian "ipm %[psw]\n\t" : [psw] "=d"(psw) \ 13735f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian : [high] "f"(hi), [low] "f"(lo) \ 13745f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian : "cc", "r0", "f4", "f6"); \ 13755f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian psw >> 28; /* cc */ \ 13765f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian }) 13775f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian 13785f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian#define S390_CC_FOR_DFP128_CONVERT(opcode,cc_dep1,cc_dep2,cc_ndep) \ 13795f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian ({ \ 13805f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian UInt cc; \ 13815f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian /* Recover the original DEP2 value. See comment near \ 13825f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian s390_cc_thunk_put3 for rationale. */ \ 13835f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc_dep2 = cc_dep2 ^ cc_ndep; \ 13845f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian switch (decode_dfp_rounding_mode(cc_ndep)) { \ 13855f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1: \ 13865f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12: \ 13875f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP128_CONVERT_AUX(opcode,cc_dep1,cc_dep2,1); \ 13885f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 13895f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_PREPARE_SHORT_3: \ 13905f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_PREPARE_SHORT_15: \ 13915f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP128_CONVERT_AUX(opcode,cc_dep1,cc_dep2,3); \ 13925f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 13935f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_EVEN_4: \ 13945f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_EVEN_8: \ 13955f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP128_CONVERT_AUX(opcode,cc_dep1,cc_dep2,4); \ 13965f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 13975f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_ZERO_5: \ 13985f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_ZERO_9: \ 13995f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP128_CONVERT_AUX(opcode,cc_dep1,cc_dep2,5); \ 14005f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 14015f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_POSINF_6: \ 14025f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_POSINF_10: \ 14035f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP128_CONVERT_AUX(opcode,cc_dep1,cc_dep2,6); \ 14045f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 14055f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEGINF_7: \ 14065f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEGINF_11: \ 14075f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP128_CONVERT_AUX(opcode,cc_dep1,cc_dep2,7); \ 14085f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 14095f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_TIE_TOWARD_0: \ 14105f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP128_CONVERT_AUX(opcode,cc_dep1,cc_dep2,13); \ 14115f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 14125f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_AWAY_0: \ 14135f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP128_CONVERT_AUX(opcode,cc_dep1,cc_dep2,14); \ 14145f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 14155f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian default: \ 14165f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian vpanic("unexpected dfp rounding mode"); \ 14175f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian } \ 14185f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc; \ 14195f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian }) 14205f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian 14215f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian#define S390_CC_FOR_DFP128_UCONVERT_AUX(opcode,hi,lo,rounding_mode) \ 14225f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian ({ \ 14235f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian __asm__ volatile ( \ 14245f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian "ldr 4,%[high]\n\t" \ 14255f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian "ldr 6,%[low]\n\t" \ 14265f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian opcode ",0,4," #rounding_mode ",0\n\t" \ 14275f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian "ipm %[psw]\n\t" : [psw] "=d"(psw) \ 14285f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian : [high] "f"(hi), [low] "f"(lo) \ 14295f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian : "cc", "r0", "f4", "f6"); \ 14305f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian psw >> 28; /* cc */ \ 14315f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian }) 14325f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian 14335f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian#define S390_CC_FOR_DFP128_UCONVERT(opcode,cc_dep1,cc_dep2,cc_ndep) \ 14345f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian ({ \ 14355f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian UInt cc; \ 14365f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian /* Recover the original DEP2 value. See comment near \ 14375f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian s390_cc_thunk_put3 for rationale. */ \ 14385f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc_dep2 = cc_dep2 ^ cc_ndep; \ 14395f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian switch (decode_dfp_rounding_mode(cc_ndep)) { \ 14405f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_1: \ 14415f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_TIE_AWAY_0_12: \ 14425f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP128_UCONVERT_AUX(opcode,cc_dep1,cc_dep2,1); \ 14435f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 14445f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_PREPARE_SHORT_3: \ 14455f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_PREPARE_SHORT_15: \ 14465f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP128_UCONVERT_AUX(opcode,cc_dep1,cc_dep2,3); \ 14475f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 14485f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_EVEN_4: \ 14495f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_EVEN_8: \ 14505f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP128_UCONVERT_AUX(opcode,cc_dep1,cc_dep2,4); \ 14515f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 14525f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_ZERO_5: \ 14535f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_ZERO_9: \ 14545f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP128_UCONVERT_AUX(opcode,cc_dep1,cc_dep2,5); \ 14555f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 14565f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_POSINF_6: \ 14575f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_POSINF_10: \ 14585f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP128_UCONVERT_AUX(opcode,cc_dep1,cc_dep2,6); \ 14595f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 14605f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEGINF_7: \ 14615f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEGINF_11: \ 14625f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP128_UCONVERT_AUX(opcode,cc_dep1,cc_dep2,7); \ 14635f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 14645f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_NEAREST_TIE_TOWARD_0: \ 14655f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP128_UCONVERT_AUX(opcode,cc_dep1,cc_dep2,13); \ 14665f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 14675f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_DFP_ROUND_AWAY_0: \ 14685f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc = S390_CC_FOR_DFP128_UCONVERT_AUX(opcode,cc_dep1,cc_dep2,14); \ 14695f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian break; \ 14705f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian default: \ 14715f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian vpanic("unexpected dfp rounding mode"); \ 14725f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian } \ 14735f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc; \ 14745f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian }) 14755f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian 14762019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 14772019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/* Return the value of the condition code from the supplied thunk parameters. 14782019a976f07ff418dde2dfc7cc74667ef66d7764sewardj This is not the value of the PSW. It is the value of the 2 CC bits within 14792019a976f07ff418dde2dfc7cc74667ef66d7764sewardj the PSW. The returned value is thusly in the interval [0:3]. */ 14802019a976f07ff418dde2dfc7cc74667ef66d7764sewardjUInt 14812019a976f07ff418dde2dfc7cc74667ef66d7764sewardjs390_calculate_cc(ULong cc_op, ULong cc_dep1, ULong cc_dep2, ULong cc_ndep) 14822019a976f07ff418dde2dfc7cc74667ef66d7764sewardj{ 14832019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#if defined(VGA_s390x) 14842019a976f07ff418dde2dfc7cc74667ef66d7764sewardj UInt psw; 14852019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 14862019a976f07ff418dde2dfc7cc74667ef66d7764sewardj switch (cc_op) { 14872019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 14882019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_BITWISE: 14892019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_BINARY("ogr", cc_dep1, (ULong)0); 14902019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 14912019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_SIGNED_COMPARE: 14922019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_BINARY("cgr", cc_dep1, cc_dep2); 14932019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 14942019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_UNSIGNED_COMPARE: 14952019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_BINARY("clgr", cc_dep1, cc_dep2); 14962019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 14972019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_SIGNED_ADD_64: 14982019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_BINARY("agr", cc_dep1, cc_dep2); 14992019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15002019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_SIGNED_ADD_32: 15012019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_BINARY("ar", cc_dep1, cc_dep2); 15022019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15032019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_SIGNED_SUB_64: 15042019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_BINARY("sgr", cc_dep1, cc_dep2); 15052019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15062019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_SIGNED_SUB_32: 15072019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_BINARY("sr", cc_dep1, cc_dep2); 15082019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15092019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_UNSIGNED_ADD_64: 15102019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_BINARY("algr", cc_dep1, cc_dep2); 15112019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15122019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_UNSIGNED_ADD_32: 15132019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_BINARY("alr", cc_dep1, cc_dep2); 15142019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15152019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_UNSIGNED_ADDC_64: 15162019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_TERNARY_ADDC("alcgr", cc_dep1, cc_dep2, cc_ndep); 15172019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15182019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_UNSIGNED_ADDC_32: 15192019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_TERNARY_ADDC("alcr", cc_dep1, cc_dep2, cc_ndep); 15202019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15212019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_UNSIGNED_SUB_64: 15222019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_BINARY("slgr", cc_dep1, cc_dep2); 15232019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15242019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_UNSIGNED_SUB_32: 15252019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_BINARY("slr", cc_dep1, cc_dep2); 15262019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15272019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_UNSIGNED_SUBB_64: 15282019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_TERNARY_SUBB("slbgr", cc_dep1, cc_dep2, cc_ndep); 15292019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15302019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_UNSIGNED_SUBB_32: 15312019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_TERNARY_SUBB("slbr", cc_dep1, cc_dep2, cc_ndep); 15322019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15332019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_LOAD_AND_TEST: 15342019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Like signed comparison with 0 */ 15352019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_BINARY("cgr", cc_dep1, (Long)0); 15362019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15372019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_LOAD_POSITIVE_32: 15382019a976f07ff418dde2dfc7cc74667ef66d7764sewardj __asm__ volatile ( 15392019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "lpr %[result],%[op]\n\t" 1540ae88411aaa8e0b99032fb0bdb04eec21edc54d88florian "ipm %[psw]\n\t" : [psw] "=d"(psw), [result] "=d"(cc_dep1) 1541ae88411aaa8e0b99032fb0bdb04eec21edc54d88florian : [op] "d"(cc_dep1) 1542ae88411aaa8e0b99032fb0bdb04eec21edc54d88florian : "cc"); 15432019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return psw >> 28; /* cc */ 15442019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15452019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_LOAD_POSITIVE_64: 15462019a976f07ff418dde2dfc7cc74667ef66d7764sewardj __asm__ volatile ( 15472019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "lpgr %[result],%[op]\n\t" 1548ae88411aaa8e0b99032fb0bdb04eec21edc54d88florian "ipm %[psw]\n\t" : [psw] "=d"(psw), [result] "=d"(cc_dep1) 1549ae88411aaa8e0b99032fb0bdb04eec21edc54d88florian : [op] "d"(cc_dep1) 1550ae88411aaa8e0b99032fb0bdb04eec21edc54d88florian : "cc"); 15512019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return psw >> 28; /* cc */ 15522019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15532019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_TEST_UNDER_MASK_8: { 15542019a976f07ff418dde2dfc7cc74667ef66d7764sewardj UChar value = cc_dep1; 15552019a976f07ff418dde2dfc7cc74667ef66d7764sewardj UChar mask = cc_dep2; 15562019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15572019a976f07ff418dde2dfc7cc74667ef66d7764sewardj __asm__ volatile ( 15582019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "bras %%r2,1f\n\t" /* %r2 = address of next insn */ 15592019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "tm %[value],0\n\t" /* this is skipped, then EXecuted */ 15602019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "1: ex %[mask],0(%%r2)\n\t" /* EXecute TM after modifying mask */ 15612019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ipm %[psw]\n\t" : [psw] "=d"(psw) 15622019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : [value] "m"(value), [mask] "a"(mask) 15632019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : "r2", "cc"); 15642019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return psw >> 28; /* cc */ 15652019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 15662019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15672019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_TEST_UNDER_MASK_16: { 15682019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Create a TMLL insn with the mask as given by cc_dep2 */ 15698cf6637c6d45e8b1c514a658e7290cd5738b1d7dflorian UInt insn = (0xA701u << 16) | cc_dep2; 15702019a976f07ff418dde2dfc7cc74667ef66d7764sewardj UInt value = cc_dep1; 15712019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15722019a976f07ff418dde2dfc7cc74667ef66d7764sewardj __asm__ volatile ( 15732019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "lr 1,%[value]\n\t" 15742019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "lhi 2,0x10\n\t" 15752019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ex 2,%[insn]\n\t" 15762019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ipm %[psw]\n\t" : [psw] "=d"(psw) 15772019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : [value] "d"(value), [insn] "m"(insn) 15782019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : "r1", "r2", "cc"); 15792019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return psw >> 28; /* cc */ 15802019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 15812019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15822019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_SHIFT_LEFT_32: 15832019a976f07ff418dde2dfc7cc74667ef66d7764sewardj __asm__ volatile ( 15842019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "sla %[op],0(%[amount])\n\t" 15852019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "ipm %[psw]\n\t" : [psw] "=d"(psw), [op] "+d"(cc_dep1) 15862019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : [amount] "a"(cc_dep2) 15872019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : "cc"); 15882019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return psw >> 28; /* cc */ 15892019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15902019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_SHIFT_LEFT_64: { 15912019a976f07ff418dde2dfc7cc74667ef66d7764sewardj Int high = (Int)(cc_dep1 >> 32); 15922019a976f07ff418dde2dfc7cc74667ef66d7764sewardj Int low = (Int)(cc_dep1 & 0xFFFFFFFF); 15932019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 15942019a976f07ff418dde2dfc7cc74667ef66d7764sewardj __asm__ volatile ( 15952019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "lr 2,%[high]\n\t" 15962019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "lr 3,%[low]\n\t" 15972019a976f07ff418dde2dfc7cc74667ef66d7764sewardj "slda 2,0(%[amount])\n\t" 1598ae88411aaa8e0b99032fb0bdb04eec21edc54d88florian "ipm %[psw]\n\t" : [psw] "=d"(psw), [high] "+d"(high), 1599ae88411aaa8e0b99032fb0bdb04eec21edc54d88florian [low] "+d"(low) 16002019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : [amount] "a"(cc_dep2) 16012019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : "cc", "r2", "r3"); 16022019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return psw >> 28; /* cc */ 16032019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 16042019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 16052019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_INSERT_CHAR_MASK_32: { 16062019a976f07ff418dde2dfc7cc74667ef66d7764sewardj Int inserted = 0; 16072019a976f07ff418dde2dfc7cc74667ef66d7764sewardj Int msb = 0; 16082019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 16092019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cc_dep2 & 1) { 16102019a976f07ff418dde2dfc7cc74667ef66d7764sewardj inserted |= cc_dep1 & 0xff; 16112019a976f07ff418dde2dfc7cc74667ef66d7764sewardj msb = 0x80; 16122019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 16132019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cc_dep2 & 2) { 16142019a976f07ff418dde2dfc7cc74667ef66d7764sewardj inserted |= cc_dep1 & 0xff00; 16152019a976f07ff418dde2dfc7cc74667ef66d7764sewardj msb = 0x8000; 16162019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 16172019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cc_dep2 & 4) { 16182019a976f07ff418dde2dfc7cc74667ef66d7764sewardj inserted |= cc_dep1 & 0xff0000; 16192019a976f07ff418dde2dfc7cc74667ef66d7764sewardj msb = 0x800000; 16202019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 16212019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cc_dep2 & 8) { 16222019a976f07ff418dde2dfc7cc74667ef66d7764sewardj inserted |= cc_dep1 & 0xff000000; 16232019a976f07ff418dde2dfc7cc74667ef66d7764sewardj msb = 0x80000000; 16242019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 16252019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 16262019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (inserted & msb) // MSB is 1 16272019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return 1; 16282019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (inserted > 0) 16292019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return 2; 16302019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return 0; 16312019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 16322019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 16332019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_BFP_RESULT_32: 16342019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_BFP_RESULT("ltebr", cc_dep1); 16352019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 16362019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_BFP_RESULT_64: 16372019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_BFP_RESULT("ltdbr", cc_dep1); 16382019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 16392019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_BFP_RESULT_128: 16402019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_BFP128_RESULT(cc_dep1, cc_dep2); 16412019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 16422019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_BFP_32_TO_INT_32: 164319e0077d31fe17496eeb76cd008507d1a8f75908florian return S390_CC_FOR_BFP_CONVERT("cfebr", cc_dep1, cc_dep2); 16442019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 16452019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_BFP_64_TO_INT_32: 164619e0077d31fe17496eeb76cd008507d1a8f75908florian return S390_CC_FOR_BFP_CONVERT("cfdbr", cc_dep1, cc_dep2); 16472019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 16482019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_BFP_128_TO_INT_32: 164919e0077d31fe17496eeb76cd008507d1a8f75908florian return S390_CC_FOR_BFP128_CONVERT("cfxbr", cc_dep1, cc_dep2, cc_ndep); 16502019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 16512019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_BFP_32_TO_INT_64: 165219e0077d31fe17496eeb76cd008507d1a8f75908florian return S390_CC_FOR_BFP_CONVERT("cgebr", cc_dep1, cc_dep2); 16532019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 16542019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_BFP_64_TO_INT_64: 165519e0077d31fe17496eeb76cd008507d1a8f75908florian return S390_CC_FOR_BFP_CONVERT("cgdbr", cc_dep1, cc_dep2); 16562019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 16572019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_BFP_128_TO_INT_64: 165819e0077d31fe17496eeb76cd008507d1a8f75908florian return S390_CC_FOR_BFP128_CONVERT("cgxbr", cc_dep1, cc_dep2, cc_ndep); 16592019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 16602019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_BFP_TDC_32: 16612019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_BFP_TDC("tceb", cc_dep1, cc_dep2); 16622019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 16632019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_BFP_TDC_64: 16642019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_BFP_TDC("tcdb", cc_dep1, cc_dep2); 16652019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 16662019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_BFP_TDC_128: 16672019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return S390_CC_FOR_BFP128_TDC(cc_dep1, cc_dep2, cc_ndep); 16682019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 16692019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case S390_CC_OP_SET: 16702019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return cc_dep1; 16712019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 16721c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian case S390_CC_OP_BFP_32_TO_UINT_32: 167319e0077d31fe17496eeb76cd008507d1a8f75908florian return S390_CC_FOR_BFP_UCONVERT(".insn rrf,0xb39c0000", cc_dep1, cc_dep2); 16741c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian 16751c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian case S390_CC_OP_BFP_64_TO_UINT_32: 167619e0077d31fe17496eeb76cd008507d1a8f75908florian return S390_CC_FOR_BFP_UCONVERT(".insn rrf,0xb39d0000", cc_dep1, cc_dep2); 16771c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian 16781c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian case S390_CC_OP_BFP_128_TO_UINT_32: 167919e0077d31fe17496eeb76cd008507d1a8f75908florian return S390_CC_FOR_BFP128_UCONVERT(".insn rrf,0xb39e0000", cc_dep1, 168019e0077d31fe17496eeb76cd008507d1a8f75908florian cc_dep2, cc_ndep); 16811c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian 16821c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian case S390_CC_OP_BFP_32_TO_UINT_64: 168319e0077d31fe17496eeb76cd008507d1a8f75908florian return S390_CC_FOR_BFP_UCONVERT(".insn rrf,0xb3ac0000", cc_dep1, cc_dep2); 16841c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian 16851c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian case S390_CC_OP_BFP_64_TO_UINT_64: 168619e0077d31fe17496eeb76cd008507d1a8f75908florian return S390_CC_FOR_BFP_UCONVERT(".insn rrf,0xb3ad0000", cc_dep1, cc_dep2); 16871c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian 16881c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian case S390_CC_OP_BFP_128_TO_UINT_64: 168919e0077d31fe17496eeb76cd008507d1a8f75908florian return S390_CC_FOR_BFP128_UCONVERT(".insn rrf,0xb3ae0000", cc_dep1, 169019e0077d31fe17496eeb76cd008507d1a8f75908florian cc_dep2, cc_ndep); 16911c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian 16921239020c948a6e20faaa8d0fa5dea44302e18f8aflorian case S390_CC_OP_DFP_RESULT_64: 16931239020c948a6e20faaa8d0fa5dea44302e18f8aflorian return S390_CC_FOR_DFP_RESULT(cc_dep1); 16941c8f7ff5e4682f2ea5c33b514881d97e5dbc11ebflorian 1695e38f641461120ea338069a3f45820168959968abflorian case S390_CC_OP_DFP_RESULT_128: 1696e38f641461120ea338069a3f45820168959968abflorian return S390_CC_FOR_DFP128_RESULT(cc_dep1, cc_dep2); 1697e38f641461120ea338069a3f45820168959968abflorian 1698ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian case S390_CC_OP_DFP_TDC_32: /* TDCET */ 1699ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian return S390_CC_FOR_DFP_TD(".insn rxe, 0xed0000000050", cc_dep1, cc_dep2); 1700ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian 1701ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian case S390_CC_OP_DFP_TDC_64: /* TDCDT */ 1702ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian return S390_CC_FOR_DFP_TD(".insn rxe, 0xed0000000054", cc_dep1, cc_dep2); 1703ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian 1704ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian case S390_CC_OP_DFP_TDC_128: /* TDCXT */ 1705ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian return S390_CC_FOR_DFP128_TD(".insn rxe, 0xed0000000058", cc_dep1, 1706ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian cc_dep2, cc_ndep); 1707ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian 1708ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian case S390_CC_OP_DFP_TDG_32: /* TDGET */ 1709ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian return S390_CC_FOR_DFP_TD(".insn rxe, 0xed0000000051", cc_dep1, cc_dep2); 1710ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian 1711ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian case S390_CC_OP_DFP_TDG_64: /* TDGDT */ 1712ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian return S390_CC_FOR_DFP_TD(".insn rxe, 0xed0000000055", cc_dep1, cc_dep2); 1713ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian 1714ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian case S390_CC_OP_DFP_TDG_128: /* TDGXT */ 1715ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian return S390_CC_FOR_DFP128_TD(".insn rxe, 0xed0000000059", cc_dep1, 1716ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian cc_dep2, cc_ndep); 1717ce9e3dbfe4342b2f9684f2bd3acf06d172982efeflorian 17185f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_CC_OP_DFP_64_TO_INT_32: /* CFDTR */ 17195f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian return S390_CC_FOR_DFP_CONVERT(".insn rrf,0xb9410000", cc_dep1, cc_dep2); 17205f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian 17215f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_CC_OP_DFP_128_TO_INT_32: /* CFXTR */ 17225f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian return S390_CC_FOR_DFP128_CONVERT(".insn rrf,0xb9490000", cc_dep1, 17235f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc_dep2, cc_ndep); 17245f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian 1725a887acd341cb9b90b1dd6d3fdfa4a429f5ddd583florian case S390_CC_OP_DFP_64_TO_INT_64: /* CGDTR */ 1726a887acd341cb9b90b1dd6d3fdfa4a429f5ddd583florian return S390_CC_FOR_DFP_CONVERT(".insn rrf,0xb3e10000", cc_dep1, cc_dep2); 1727a887acd341cb9b90b1dd6d3fdfa4a429f5ddd583florian 1728a887acd341cb9b90b1dd6d3fdfa4a429f5ddd583florian case S390_CC_OP_DFP_128_TO_INT_64: /* CGXTR */ 1729a887acd341cb9b90b1dd6d3fdfa4a429f5ddd583florian return S390_CC_FOR_DFP128_CONVERT(".insn rrf,0xb3e90000", cc_dep1, 1730a887acd341cb9b90b1dd6d3fdfa4a429f5ddd583florian cc_dep2, cc_ndep); 1731a887acd341cb9b90b1dd6d3fdfa4a429f5ddd583florian 17325f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_CC_OP_DFP_64_TO_UINT_32: /* CLFDTR */ 17335f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian return S390_CC_FOR_DFP_UCONVERT(".insn rrf,0xb9430000", cc_dep1, cc_dep2); 17345f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian 17355f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_CC_OP_DFP_128_TO_UINT_32: /* CLFXTR */ 17365f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian return S390_CC_FOR_DFP128_UCONVERT(".insn rrf,0xb94b0000", cc_dep1, 17375f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc_dep2, cc_ndep); 17385f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian 17395f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_CC_OP_DFP_64_TO_UINT_64: /* CLGDTR */ 17405f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian return S390_CC_FOR_DFP_UCONVERT(".insn rrf,0xb9420000", cc_dep1, cc_dep2); 17415f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian 17425f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian case S390_CC_OP_DFP_128_TO_UINT_64: /* CLGXTR */ 17435f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian return S390_CC_FOR_DFP128_UCONVERT(".insn rrf,0xb94a0000", cc_dep1, 17445f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian cc_dep2, cc_ndep); 17455f03462774bbec01825dfd3c2bcc9ed7b8b7c3a3florian 17467ab421d8483f8462f2bf5ebdd1ef5d72658dd572florian case S390_CC_OP_PFPO_32: { 17477ab421d8483f8462f2bf5ebdd1ef5d72658dd572florian __asm__ volatile( 17487ab421d8483f8462f2bf5ebdd1ef5d72658dd572florian "ler 4, %[cc_dep1]\n\t" /* 32 bit FR move */ 17497ab421d8483f8462f2bf5ebdd1ef5d72658dd572florian "lr 0, %[cc_dep2]\n\t" /* 32 bit GR move */ 17507ab421d8483f8462f2bf5ebdd1ef5d72658dd572florian ".short 0x010a\n\t" /* PFPO */ 17517ab421d8483f8462f2bf5ebdd1ef5d72658dd572florian "ipm %[psw]\n\t" : [psw] "=d"(psw) 17527ab421d8483f8462f2bf5ebdd1ef5d72658dd572florian : [cc_dep1] "f"(cc_dep1), 17537ab421d8483f8462f2bf5ebdd1ef5d72658dd572florian [cc_dep2] "d"(cc_dep2) 17547ab421d8483f8462f2bf5ebdd1ef5d72658dd572florian : "r0", "r1", "f4"); 17557ab421d8483f8462f2bf5ebdd1ef5d72658dd572florian return psw >> 28; /* cc */ 17567ab421d8483f8462f2bf5ebdd1ef5d72658dd572florian } 17577ab421d8483f8462f2bf5ebdd1ef5d72658dd572florian 175878d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian case S390_CC_OP_PFPO_64: { 175978d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian __asm__ volatile( 176078d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian "ldr 4, %[cc_dep1]\n\t" 176178d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian "lr 0, %[cc_dep2]\n\t" /* 32 bit register move */ 176278d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian ".short 0x010a\n\t" /* PFPO */ 176378d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian "ipm %[psw]\n\t" : [psw] "=d"(psw) 1764c589228fe86255c87fdc9ad78d5d9c60e4c9e61eflorian : [cc_dep1] "f"(cc_dep1), 1765c589228fe86255c87fdc9ad78d5d9c60e4c9e61eflorian [cc_dep2] "d"(cc_dep2) 176678d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian : "r0", "r1", "f4"); 176778d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian return psw >> 28; /* cc */ 176878d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian } 176978d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian 177078d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian case S390_CC_OP_PFPO_128: { 177178d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian __asm__ volatile( 177278d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian "ldr 4,%[cc_dep1]\n\t" 177378d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian "ldr 6,%[cc_dep2]\n\t" 177478d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian "lr 0,%[cc_ndep]\n\t" /* 32 bit register move */ 177578d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian ".short 0x010a\n\t" /* PFPO */ 177678d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian "ipm %[psw]\n\t" : [psw] "=d"(psw) 177778d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian : [cc_dep1] "f"(cc_dep1), 177878d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian [cc_dep2] "f"(cc_dep2), 177978d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian [cc_ndep] "d"(cc_ndep) 178078d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian : "r0", "r1", "f0", "f2", "f4", "f6"); 178178d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian return psw >> 28; /* cc */ 178278d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian } 178378d5ef75d89e5aa6c629a2d47f7e04ddbf1253c3florian 17842019a976f07ff418dde2dfc7cc74667ef66d7764sewardj default: 17852019a976f07ff418dde2dfc7cc74667ef66d7764sewardj break; 17862019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 17872019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#endif 17882019a976f07ff418dde2dfc7cc74667ef66d7764sewardj vpanic("s390_calculate_cc"); 17892019a976f07ff418dde2dfc7cc74667ef66d7764sewardj} 17902019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 17912019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 17922019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/* Note that this does *not* return a Boolean value. The result needs to be 17932019a976f07ff418dde2dfc7cc74667ef66d7764sewardj explicitly tested against zero. */ 17942019a976f07ff418dde2dfc7cc74667ef66d7764sewardjUInt 17952019a976f07ff418dde2dfc7cc74667ef66d7764sewardjs390_calculate_cond(ULong mask, ULong op, ULong dep1, ULong dep2, ULong ndep) 17962019a976f07ff418dde2dfc7cc74667ef66d7764sewardj{ 17972019a976f07ff418dde2dfc7cc74667ef66d7764sewardj UInt cc = s390_calculate_cc(op, dep1, dep2, ndep); 17982019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 17992019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return ((mask << cc) & 0x8); 18002019a976f07ff418dde2dfc7cc74667ef66d7764sewardj} 18012019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18022019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*------------------------------------------------------------*/ 18032019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*--- spechelper for performance ---*/ 18042019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*------------------------------------------------------------*/ 18052019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18062019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18072019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/* Convenience macros */ 18082019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#define unop(op,a1) IRExpr_Unop((op),(a1)) 18092019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#define binop(op,a1,a2) IRExpr_Binop((op),(a1),(a2)) 18102019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#define mkU64(v) IRExpr_Const(IRConst_U64(v)) 18112019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#define mkU32(v) IRExpr_Const(IRConst_U32(v)) 18122019a976f07ff418dde2dfc7cc74667ef66d7764sewardj#define mkU8(v) IRExpr_Const(IRConst_U8(v)) 18132019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18142019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18152019a976f07ff418dde2dfc7cc74667ef66d7764sewardjstatic inline Bool 181649adf8664fa8e67c95397022d21ea1b547e2186bflorianisC64(const IRExpr *expr) 18172019a976f07ff418dde2dfc7cc74667ef66d7764sewardj{ 18182019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return expr->tag == Iex_Const && expr->Iex.Const.con->tag == Ico_U64; 18192019a976f07ff418dde2dfc7cc74667ef66d7764sewardj} 18202019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18212019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18222019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/* The returned expression is NULL if no specialization was found. In that 18232019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case the helper function will be called. Otherwise, the expression has 18242019a976f07ff418dde2dfc7cc74667ef66d7764sewardj type Ity_I32 and a Boolean value. */ 18252019a976f07ff418dde2dfc7cc74667ef66d7764sewardjIRExpr * 18261ff4756e1731485e6bf3cd96717cd8398daec1f2florianguest_s390x_spechelper(const HChar *function_name, IRExpr **args, 18272019a976f07ff418dde2dfc7cc74667ef66d7764sewardj IRStmt **precedingStmts, Int n_precedingStmts) 18282019a976f07ff418dde2dfc7cc74667ef66d7764sewardj{ 18292019a976f07ff418dde2dfc7cc74667ef66d7764sewardj UInt i, arity = 0; 18302019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18312019a976f07ff418dde2dfc7cc74667ef66d7764sewardj for (i = 0; args[i]; i++) 18322019a976f07ff418dde2dfc7cc74667ef66d7764sewardj arity++; 18332019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18342019a976f07ff418dde2dfc7cc74667ef66d7764sewardj# if 0 18352019a976f07ff418dde2dfc7cc74667ef66d7764sewardj vex_printf("spec request:\n"); 18362019a976f07ff418dde2dfc7cc74667ef66d7764sewardj vex_printf(" %s ", function_name); 18372019a976f07ff418dde2dfc7cc74667ef66d7764sewardj for (i = 0; i < arity; i++) { 18382019a976f07ff418dde2dfc7cc74667ef66d7764sewardj vex_printf(" "); 18392019a976f07ff418dde2dfc7cc74667ef66d7764sewardj ppIRExpr(args[i]); 18402019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 18412019a976f07ff418dde2dfc7cc74667ef66d7764sewardj vex_printf("\n"); 18422019a976f07ff418dde2dfc7cc74667ef66d7764sewardj# endif 18432019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18442019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* --------- Specialising "s390_calculate_cond" --------- */ 18452019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18462019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (vex_streq(function_name, "s390_calculate_cond")) { 18472019a976f07ff418dde2dfc7cc74667ef66d7764sewardj IRExpr *cond_expr, *cc_op_expr, *cc_dep1, *cc_dep2; 18482019a976f07ff418dde2dfc7cc74667ef66d7764sewardj ULong cond, cc_op; 18492019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18502019a976f07ff418dde2dfc7cc74667ef66d7764sewardj vassert(arity == 5); 18512019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18522019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cond_expr = args[0]; 18532019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc_op_expr = args[1]; 18542019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18552019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* The necessary requirement for all optimizations here is that the 18562019a976f07ff418dde2dfc7cc74667ef66d7764sewardj condition and the cc_op are constant. So check that upfront. */ 18572019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (! isC64(cond_expr)) return NULL; 18582019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (! isC64(cc_op_expr)) return NULL; 18592019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18602019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cond = cond_expr->Iex.Const.con->Ico.U64; 18612019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc_op = cc_op_expr->Iex.Const.con->Ico.U64; 18622019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18632019a976f07ff418dde2dfc7cc74667ef66d7764sewardj vassert(cond <= 15); 18642019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18652019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* 18662019a976f07ff418dde2dfc7cc74667ef66d7764sewardj +------+---+---+---+---+ 18672019a976f07ff418dde2dfc7cc74667ef66d7764sewardj | cc | 0 | 1 | 2 | 3 | 18682019a976f07ff418dde2dfc7cc74667ef66d7764sewardj | cond | 8 | 4 | 2 | 1 | 18692019a976f07ff418dde2dfc7cc74667ef66d7764sewardj +------+---+---+---+---+ 18702019a976f07ff418dde2dfc7cc74667ef66d7764sewardj */ 18712019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc_dep1 = args[2]; 18722019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc_dep2 = args[3]; 18732019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18742019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* S390_CC_OP_SIGNED_COMPARE */ 18752019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cc_op == S390_CC_OP_SIGNED_COMPARE) { 18762019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* 18772019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 0 --> cc_dep1 == cc_dep2 (cond == 8) 18782019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 1 --> cc_dep1 < cc_dep2 (cond == 4) 18792019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 2 --> cc_dep1 > cc_dep2 (cond == 2) 18802019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 18812019a976f07ff418dde2dfc7cc74667ef66d7764sewardj Because cc == 3 cannot occur the rightmost bit of cond is 18822019a976f07ff418dde2dfc7cc74667ef66d7764sewardj a don't care. 18832019a976f07ff418dde2dfc7cc74667ef66d7764sewardj */ 18842019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 || cond == 8 + 1) { 18852019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpEQ64, cc_dep1, cc_dep2)); 18862019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 18872019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 4 + 2 || cond == 4 + 2 + 1) { 18882019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpNE64, cc_dep1, cc_dep2)); 18892019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 18902019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 4 || cond == 4 + 1) { 18912019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpLT64S, cc_dep1, cc_dep2)); 18922019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 18932019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 + 4 || cond == 8 + 4 + 1) { 18942019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpLE64S, cc_dep1, cc_dep2)); 18952019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 18962019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* cc_dep1 > cc_dep2 ----> cc_dep2 < cc_dep1 */ 18972019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 2 || cond == 2 + 1) { 18982019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpLT64S, cc_dep2, cc_dep1)); 18992019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19002019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 + 2 || cond == 8 + 2 + 1) { 19012019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpLE64S, cc_dep2, cc_dep1)); 19022019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19032019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 + 4 + 2 || cond == 8 + 4 + 2 + 1) { 19042019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return mkU32(1); 19052019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19062019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Remaining case */ 19072019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return mkU32(0); 19082019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19092019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 19102019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* S390_CC_OP_UNSIGNED_COMPARE */ 19112019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cc_op == S390_CC_OP_UNSIGNED_COMPARE) { 19122019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* 19132019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 0 --> cc_dep1 == cc_dep2 (cond == 8) 19142019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 1 --> cc_dep1 < cc_dep2 (cond == 4) 19152019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 2 --> cc_dep1 > cc_dep2 (cond == 2) 19162019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 19172019a976f07ff418dde2dfc7cc74667ef66d7764sewardj Because cc == 3 cannot occur the rightmost bit of cond is 19182019a976f07ff418dde2dfc7cc74667ef66d7764sewardj a don't care. 19192019a976f07ff418dde2dfc7cc74667ef66d7764sewardj */ 19202019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 || cond == 8 + 1) { 19212019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpEQ64, cc_dep1, cc_dep2)); 19222019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19232019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 4 + 2 || cond == 4 + 2 + 1) { 19242019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpNE64, cc_dep1, cc_dep2)); 19252019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19262019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 4 || cond == 4 + 1) { 19272019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpLT64U, cc_dep1, cc_dep2)); 19282019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19292019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 + 4 || cond == 8 + 4 + 1) { 19302019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpLE64U, cc_dep1, cc_dep2)); 19312019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19322019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* cc_dep1 > cc_dep2 ----> cc_dep2 < cc_dep1 */ 19332019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 2 || cond == 2 + 1) { 19342019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpLT64U, cc_dep2, cc_dep1)); 19352019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19362019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 + 2 || cond == 8 + 2 + 1) { 19372019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpLE64U, cc_dep2, cc_dep1)); 19382019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19392019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 + 4 + 2 || cond == 8 + 4 + 2 + 1) { 19402019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return mkU32(1); 19412019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19422019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Remaining case */ 19432019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return mkU32(0); 19442019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19452019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 19462019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* S390_CC_OP_LOAD_AND_TEST */ 19472019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cc_op == S390_CC_OP_LOAD_AND_TEST) { 19482019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* 19492019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 0 --> cc_dep1 == 0 (cond == 8) 19502019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 1 --> cc_dep1 < 0 (cond == 4) 19512019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 2 --> cc_dep1 > 0 (cond == 2) 19522019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 19532019a976f07ff418dde2dfc7cc74667ef66d7764sewardj Because cc == 3 cannot occur the rightmost bit of cond is 19542019a976f07ff418dde2dfc7cc74667ef66d7764sewardj a don't care. 19552019a976f07ff418dde2dfc7cc74667ef66d7764sewardj */ 19562019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 || cond == 8 + 1) { 19572019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpEQ64, cc_dep1, mkU64(0))); 19582019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19592019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 4 + 2 || cond == 4 + 2 + 1) { 19602019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpNE64, cc_dep1, mkU64(0))); 19612019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19622019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 4 || cond == 4 + 1) { 196318bf154f1c34d8234fb25f63a3b906b46009930ccborntra /* Special case cc_dep < 0. Only check the MSB to avoid bogus 196418bf154f1c34d8234fb25f63a3b906b46009930ccborntra memcheck complaints due to gcc magic. Fixes 343802 196518bf154f1c34d8234fb25f63a3b906b46009930ccborntra */ 196618bf154f1c34d8234fb25f63a3b906b46009930ccborntra return unop(Iop_64to32, binop(Iop_Shr64, cc_dep1, mkU8(63))); 19672019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19682019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 + 4 || cond == 8 + 4 + 1) { 19692019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpLE64S, cc_dep1, mkU64(0))); 19702019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19712019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* cc_dep1 > 0 ----> 0 < cc_dep1 */ 19722019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 2 || cond == 2 + 1) { 19732019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpLT64S, mkU64(0), cc_dep1)); 19742019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19752019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 + 2 || cond == 8 + 2 + 1) { 197625e1cb271253c82bc8610820004116bad5e8d0a1florian /* Special case cc_dep >= 0. Only check the MSB to avoid bogus 197725e1cb271253c82bc8610820004116bad5e8d0a1florian memcheck complaints due to gcc magic. Fixes 308427 1978d7f19c077688845dcea5a037fe42ab5b1f7db717cborntra */ 197925e1cb271253c82bc8610820004116bad5e8d0a1florian return unop(Iop_64to32, binop(Iop_Xor64, 198025e1cb271253c82bc8610820004116bad5e8d0a1florian binop(Iop_Shr64, cc_dep1, mkU8(63)), 198125e1cb271253c82bc8610820004116bad5e8d0a1florian mkU64(1))); 19822019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19832019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 + 4 + 2 || cond == 8 + 4 + 2 + 1) { 19842019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return mkU32(1); 19852019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19862019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Remaining case */ 19872019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return mkU32(0); 19882019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 19892019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 19902019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* S390_CC_OP_BITWISE */ 19912019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cc_op == S390_CC_OP_BITWISE) { 19922019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* 19932019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc_dep1 is the result of the boolean operation. 19942019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 19952019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 0 --> cc_dep1 == 0 (cond == 8) 19962019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 1 --> cc_dep1 != 0 (cond == 4) 19972019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 19982019a976f07ff418dde2dfc7cc74667ef66d7764sewardj Because cc == 2 and cc == 3 cannot occur the two rightmost bits of 19992019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cond are don't cares. Therefore: 20002019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 20012019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cond == 00xx -> always false 20022019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cond == 01xx -> not equal 20032019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cond == 10xx -> equal 20042019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cond == 11xx -> always true 20052019a976f07ff418dde2dfc7cc74667ef66d7764sewardj */ 20062019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if ((cond & (8 + 4)) == 8 + 4) { 20072019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return mkU32(1); 20082019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 20092019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond & 8) { 20102019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpEQ64, cc_dep1, mkU64(0))); 20112019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 20122019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond & 4) { 20132019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpNE64, cc_dep1, mkU64(0))); 20142019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 20152019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Remaining case */ 20162019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return mkU32(0); 20172019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 20182019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 20192019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* S390_CC_OP_INSERT_CHAR_MASK_32 20202019a976f07ff418dde2dfc7cc74667ef66d7764sewardj Since the mask comes from an immediate field in the opcode, we 20212019a976f07ff418dde2dfc7cc74667ef66d7764sewardj expect the mask to be a constant here. That simplifies matters. */ 20222019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cc_op == S390_CC_OP_INSERT_CHAR_MASK_32) { 20232019a976f07ff418dde2dfc7cc74667ef66d7764sewardj ULong mask; 20242019a976f07ff418dde2dfc7cc74667ef66d7764sewardj UInt imask = 0, shift = 0; 20252019a976f07ff418dde2dfc7cc74667ef66d7764sewardj IRExpr *word; 20262019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 20272019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (! isC64(cc_dep2)) goto missed; 20282019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 20292019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mask = cc_dep2->Iex.Const.con->Ico.U64; 20302019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 20312019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Extract the 32-bit value from the thunk */ 20322019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 20332019a976f07ff418dde2dfc7cc74667ef66d7764sewardj word = unop(Iop_64to32, cc_dep1); 20342019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 20352019a976f07ff418dde2dfc7cc74667ef66d7764sewardj switch (mask) { 20362019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case 0: shift = 0; imask = 0x00000000; break; 20372019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case 1: shift = 24; imask = 0x000000FF; break; 20382019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case 2: shift = 16; imask = 0x0000FF00; break; 20392019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case 3: shift = 16; imask = 0x0000FFFF; break; 20402019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case 4: shift = 8; imask = 0x00FF0000; break; 20412019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case 5: shift = 8; imask = 0x00FF00FF; break; 20422019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case 6: shift = 8; imask = 0x00FFFF00; break; 20432019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case 7: shift = 8; imask = 0x00FFFFFF; break; 20442019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case 8: shift = 0; imask = 0xFF000000; break; 20452019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case 9: shift = 0; imask = 0xFF0000FF; break; 20462019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case 10: shift = 0; imask = 0xFF00FF00; break; 20472019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case 11: shift = 0; imask = 0xFF00FFFF; break; 20482019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case 12: shift = 0; imask = 0xFFFF0000; break; 20492019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case 13: shift = 0; imask = 0xFFFF00FF; break; 20502019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case 14: shift = 0; imask = 0xFFFFFF00; break; 20512019a976f07ff418dde2dfc7cc74667ef66d7764sewardj case 15: shift = 0; imask = 0xFFFFFFFF; break; 20522019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 20532019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 20542019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Select the bits that were inserted */ 20552019a976f07ff418dde2dfc7cc74667ef66d7764sewardj word = binop(Iop_And32, word, mkU32(imask)); 20562019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 20572019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* cc == 0 --> all inserted bits zero or mask == 0 (cond == 8) 20582019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 1 --> leftmost inserted bit is one (cond == 4) 20592019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 2 --> leftmost inserted bit is zero and not (cond == 2) 20602019a976f07ff418dde2dfc7cc74667ef66d7764sewardj all inserted bits are zero 20612019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 20622019a976f07ff418dde2dfc7cc74667ef66d7764sewardj Because cc == 0,1,2 the rightmost bit of the mask is a don't care */ 20632019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 || cond == 8 + 1) { 20642019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpEQ32, word, mkU32(0))); 20652019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 20662019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 4 + 2 || cond == 4 + 2 + 1) { 20672019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpNE32, word, mkU32(0))); 20682019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 20692019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 20702019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Sign extend */ 20712019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (shift != 0) { 20722019a976f07ff418dde2dfc7cc74667ef66d7764sewardj word = binop(Iop_Sar32, binop(Iop_Shl32, word, mkU8(shift)), 20732019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU8(shift)); 20742019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 20752019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 20762019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 4 || cond == 4 + 1) { /* word < 0 */ 20772019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpLT32S, word, mkU32(0))); 20782019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 20792019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 2 || cond == 2 + 1) { /* word > 0 */ 20802019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpLT32S, mkU32(0), word)); 20812019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 20822019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 + 4 || cond == 8 + 4 + 1) { 20832019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpLE32S, word, mkU32(0))); 20842019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 20852019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 + 2 || cond == 8 + 2 + 1) { 20862019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpLE32S, mkU32(0), word)); 20872019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 20882019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 + 4 + 2 || cond == 8 + 4 + 2 + 1) { 20892019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return mkU32(1); 20902019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 20912019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Remaining case */ 20922019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return mkU32(0); 20932019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 20942019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 20952019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* S390_CC_OP_TEST_UNDER_MASK_8 20962019a976f07ff418dde2dfc7cc74667ef66d7764sewardj Since the mask comes from an immediate field in the opcode, we 20972019a976f07ff418dde2dfc7cc74667ef66d7764sewardj expect the mask to be a constant here. That simplifies matters. */ 20982019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cc_op == S390_CC_OP_TEST_UNDER_MASK_8) { 20992019a976f07ff418dde2dfc7cc74667ef66d7764sewardj ULong mask16; 21002019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 21012019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (! isC64(cc_dep2)) goto missed; 21022019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 21032019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mask16 = cc_dep2->Iex.Const.con->Ico.U64; 21042019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 21052019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Get rid of the mask16 == 0 case first. Some of the simplifications 21062019a976f07ff418dde2dfc7cc74667ef66d7764sewardj below (e.g. for OVFL) only hold if mask16 == 0. */ 21072019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (mask16 == 0) { /* cc == 0 */ 21082019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond & 0x8) return mkU32(1); 21092019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return mkU32(0); 21102019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 21112019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 21122019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* cc == 2 is a don't care */ 21132019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 || cond == 8 + 2) { 21142019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpEQ64, 21152019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_And64, cc_dep1, cc_dep2), 21162019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(0))); 21172019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 21182019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 7 || cond == 7 - 2) { 21192019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpNE64, 21202019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_And64, cc_dep1, cc_dep2), 21212019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(0))); 21222019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 21232019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 1 || cond == 1 + 2) { 21242019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpEQ64, 21252019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_And64, cc_dep1, cc_dep2), 21262019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc_dep2)); 21272019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 21282019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 14 || cond == 14 - 2) { /* ! OVFL */ 21292019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpNE64, 21302019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_And64, cc_dep1, cc_dep2), 21312019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc_dep2)); 21322019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 21332019a976f07ff418dde2dfc7cc74667ef66d7764sewardj goto missed; 21342019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 21352019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 21362019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* S390_CC_OP_TEST_UNDER_MASK_16 21372019a976f07ff418dde2dfc7cc74667ef66d7764sewardj Since the mask comes from an immediate field in the opcode, we 21382019a976f07ff418dde2dfc7cc74667ef66d7764sewardj expect the mask to be a constant here. That simplifies matters. */ 21392019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cc_op == S390_CC_OP_TEST_UNDER_MASK_16) { 21402019a976f07ff418dde2dfc7cc74667ef66d7764sewardj ULong mask16; 21412019a976f07ff418dde2dfc7cc74667ef66d7764sewardj UInt msb; 21422019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 21432019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (! isC64(cc_dep2)) goto missed; 21442019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 21452019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mask16 = cc_dep2->Iex.Const.con->Ico.U64; 21462019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 21472019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Get rid of the mask16 == 0 case first. Some of the simplifications 21482019a976f07ff418dde2dfc7cc74667ef66d7764sewardj below (e.g. for OVFL) only hold if mask16 == 0. */ 21492019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (mask16 == 0) { /* cc == 0 */ 21502019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond & 0x8) return mkU32(1); 21512019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return mkU32(0); 21522019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 21532019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 21549ec12ea8dc0876141a714f7c0411aec9bdae6cffflorian if (cond == 15) return mkU32(1); 21559ec12ea8dc0876141a714f7c0411aec9bdae6cffflorian 21562019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8) { 21572019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpEQ64, 21582019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_And64, cc_dep1, cc_dep2), 21592019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(0))); 21602019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 21612019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 7) { 21622019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpNE64, 21632019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_And64, cc_dep1, cc_dep2), 21642019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(0))); 21652019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 21662019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 1) { 21672019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpEQ64, 21682019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_And64, cc_dep1, cc_dep2), 21692019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(mask16))); 21702019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 21712019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 14) { /* ! OVFL */ 21722019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpNE64, 21732019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_And64, cc_dep1, cc_dep2), 21742019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(mask16))); 21752019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 21762019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 21772019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Find MSB in mask */ 21782019a976f07ff418dde2dfc7cc74667ef66d7764sewardj msb = 0x8000; 21792019a976f07ff418dde2dfc7cc74667ef66d7764sewardj while (msb > mask16) 21802019a976f07ff418dde2dfc7cc74667ef66d7764sewardj msb >>= 1; 21812019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 21822019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 2) { /* cc == 2 */ 21832019a976f07ff418dde2dfc7cc74667ef66d7764sewardj IRExpr *c1, *c2; 21842019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 21852019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* (cc_dep & msb) != 0 && (cc_dep & mask16) != mask16 */ 21862019a976f07ff418dde2dfc7cc74667ef66d7764sewardj c1 = binop(Iop_CmpNE64, 21872019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_And64, cc_dep1, mkU64(msb)), mkU64(0)); 21882019a976f07ff418dde2dfc7cc74667ef66d7764sewardj c2 = binop(Iop_CmpNE64, 21892019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_And64, cc_dep1, cc_dep2), 21902019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(mask16)); 21912019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return binop(Iop_And32, unop(Iop_1Uto32, c1), 21922019a976f07ff418dde2dfc7cc74667ef66d7764sewardj unop(Iop_1Uto32, c2)); 21932019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 21942019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 21952019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 4) { /* cc == 1 */ 21962019a976f07ff418dde2dfc7cc74667ef66d7764sewardj IRExpr *c1, *c2; 21972019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 21982019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* (cc_dep & msb) == 0 && (cc_dep & mask16) != 0 */ 21992019a976f07ff418dde2dfc7cc74667ef66d7764sewardj c1 = binop(Iop_CmpEQ64, 22002019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_And64, cc_dep1, mkU64(msb)), mkU64(0)); 22012019a976f07ff418dde2dfc7cc74667ef66d7764sewardj c2 = binop(Iop_CmpNE64, 22022019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_And64, cc_dep1, cc_dep2), 22032019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(0)); 22042019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return binop(Iop_And32, unop(Iop_1Uto32, c1), 22052019a976f07ff418dde2dfc7cc74667ef66d7764sewardj unop(Iop_1Uto32, c2)); 22062019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 22072019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 22082019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 11) { /* cc == 0,2,3 */ 22092019a976f07ff418dde2dfc7cc74667ef66d7764sewardj IRExpr *c1, *c2; 22102019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 22112019a976f07ff418dde2dfc7cc74667ef66d7764sewardj c1 = binop(Iop_CmpNE64, 22122019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_And64, cc_dep1, mkU64(msb)), mkU64(0)); 22132019a976f07ff418dde2dfc7cc74667ef66d7764sewardj c2 = binop(Iop_CmpEQ64, 22142019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_And64, cc_dep1, cc_dep2), 22152019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(0)); 22162019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return binop(Iop_Or32, unop(Iop_1Uto32, c1), 22172019a976f07ff418dde2dfc7cc74667ef66d7764sewardj unop(Iop_1Uto32, c2)); 22182019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 22192019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 22202019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 3) { /* cc == 2 || cc == 3 */ 22212019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, 22222019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_CmpNE64, 22232019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_And64, cc_dep1, mkU64(msb)), 22242019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(0))); 22252019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 22262019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 12) { /* cc == 0 || cc == 1 */ 22272019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, 22282019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_CmpEQ64, 22292019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_And64, cc_dep1, mkU64(msb)), 22302019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(0))); 22312019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 22329ec12ea8dc0876141a714f7c0411aec9bdae6cffflorian if (cond == 13) { /* cc == 0 || cc == 1 || cc == 3 */ 22339ec12ea8dc0876141a714f7c0411aec9bdae6cffflorian IRExpr *c01, *c3; 22349ec12ea8dc0876141a714f7c0411aec9bdae6cffflorian 22359ec12ea8dc0876141a714f7c0411aec9bdae6cffflorian c01 = binop(Iop_CmpEQ64, binop(Iop_And64, cc_dep1, mkU64(msb)), 22369ec12ea8dc0876141a714f7c0411aec9bdae6cffflorian mkU64(0)); 22379ec12ea8dc0876141a714f7c0411aec9bdae6cffflorian c3 = binop(Iop_CmpEQ64, binop(Iop_And64, cc_dep1, cc_dep2), 22389ec12ea8dc0876141a714f7c0411aec9bdae6cffflorian mkU64(mask16)); 22399ec12ea8dc0876141a714f7c0411aec9bdae6cffflorian return binop(Iop_Or32, unop(Iop_1Uto32, c01), 22409ec12ea8dc0876141a714f7c0411aec9bdae6cffflorian unop(Iop_1Uto32, c3)); 22419ec12ea8dc0876141a714f7c0411aec9bdae6cffflorian } 22429ec12ea8dc0876141a714f7c0411aec9bdae6cffflorian // fixs390: handle cond = 5,6,9,10 (the missing cases) 22432019a976f07ff418dde2dfc7cc74667ef66d7764sewardj // vex_printf("TUM mask = 0x%llx\n", mask16); 22442019a976f07ff418dde2dfc7cc74667ef66d7764sewardj goto missed; 22452019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 22462019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 22472019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* S390_CC_OP_UNSIGNED_SUB_64/32 */ 22482019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cc_op == S390_CC_OP_UNSIGNED_SUB_64 || 22492019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc_op == S390_CC_OP_UNSIGNED_SUB_32) { 22502019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* 22512019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc_dep1, cc_dep2 are the zero extended left and right operands 22522019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 22532019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 1 --> result != 0, borrow (cond == 4) 22542019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 2 --> result == 0, no borrow (cond == 2) 22552019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 3 --> result != 0, no borrow (cond == 1) 22562019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 22572019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc = (cc_dep1 == cc_dep2) ? 2 22582019a976f07ff418dde2dfc7cc74667ef66d7764sewardj : (cc_dep1 > cc_dep2) ? 3 : 1; 22592019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 22602019a976f07ff418dde2dfc7cc74667ef66d7764sewardj Because cc == 0 cannot occur the leftmost bit of cond is 22612019a976f07ff418dde2dfc7cc74667ef66d7764sewardj a don't care. 22622019a976f07ff418dde2dfc7cc74667ef66d7764sewardj */ 22632019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 1 || cond == 1 + 8) { /* cc == 3 op2 < op1 */ 22642019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpLT64U, cc_dep2, cc_dep1)); 22652019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 22662019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 2 || cond == 2 + 8) { /* cc == 2 */ 22672019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpEQ64, cc_dep1, cc_dep2)); 22682019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 22692019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 4 || cond == 4 + 8) { /* cc == 1 */ 22702019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpLT64U, cc_dep1, cc_dep2)); 22712019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 22722019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 3 || cond == 3 + 8) { /* cc == 2 || cc == 3 */ 22732019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpLE64U, cc_dep2, cc_dep1)); 22742019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 22752019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 6 || cond == 6 + 8) { /* cc == 2 || cc == 1 */ 22762019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpLE64U, cc_dep1, cc_dep2)); 22772019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 22782019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 22792019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 5 || cond == 5 + 8) { /* cc == 3 || cc == 1 */ 22802019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpNE64, cc_dep1, cc_dep2)); 22812019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 22822019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 7 || cond == 7 + 8) { 22832019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return mkU32(1); 22842019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 22852019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Remaining case */ 22862019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return mkU32(0); 22872019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 22882019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 22892019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* S390_CC_OP_UNSIGNED_ADD_64 */ 22902019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cc_op == S390_CC_OP_UNSIGNED_ADD_64) { 22912019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* 22922019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc_dep1, cc_dep2 are the zero extended left and right operands 22932019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 22942019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 0 --> result == 0, no carry (cond == 8) 22952019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 1 --> result != 0, no carry (cond == 4) 22962019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 2 --> result == 0, carry (cond == 2) 22972019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 3 --> result != 0, carry (cond == 1) 22982019a976f07ff418dde2dfc7cc74667ef66d7764sewardj */ 22992019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8) { /* cc == 0 */ 23002019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Both inputs are 0 */ 23012019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpEQ64, 23022019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_Or64, cc_dep1, cc_dep2), 23032019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(0))); 23042019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 23052019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 7) { /* cc == 1,2,3 */ 23062019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Not both inputs are 0 */ 23072019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpNE64, 23082019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_Or64, cc_dep1, cc_dep2), 23092019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(0))); 23102019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 23112019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 + 2) { /* cc == 0,2 -> result is zero */ 23122019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpEQ64, 23132019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_Add64, cc_dep1, cc_dep2), 23142019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(0))); 23152019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 23162019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 4 + 1) { /* cc == 1,3 -> result is not zero */ 23172019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpNE64, 23182019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_Add64, cc_dep1, cc_dep2), 23192019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(0))); 23202019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 23212019a976f07ff418dde2dfc7cc74667ef66d7764sewardj goto missed; 23222019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 23232019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 23242019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* S390_CC_OP_UNSIGNED_ADD_32 */ 23252019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cc_op == S390_CC_OP_UNSIGNED_ADD_32) { 23262019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* 23272019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc_dep1, cc_dep2 are the zero extended left and right operands 23282019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 23292019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 0 --> result == 0, no carry (cond == 8) 23302019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 1 --> result != 0, no carry (cond == 4) 23312019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 2 --> result == 0, carry (cond == 2) 23322019a976f07ff418dde2dfc7cc74667ef66d7764sewardj cc == 3 --> result != 0, carry (cond == 1) 23332019a976f07ff418dde2dfc7cc74667ef66d7764sewardj */ 23342019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8) { /* cc == 0 */ 23352019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Both inputs are 0 */ 23362019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpEQ64, 23372019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_Or64, cc_dep1, cc_dep2), 23382019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(0))); 23392019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 23402019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 7) { /* cc == 1,2,3 */ 23412019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* Not both inputs are 0 */ 23422019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpNE64, 23432019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_Or64, cc_dep1, cc_dep2), 23442019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(0))); 23452019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 23462019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 8 + 2) { /* cc == 0,2 -> result is zero */ 23472019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpEQ32, 23482019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_Add32, 23492019a976f07ff418dde2dfc7cc74667ef66d7764sewardj unop(Iop_64to32, cc_dep1), 23502019a976f07ff418dde2dfc7cc74667ef66d7764sewardj unop(Iop_64to32, cc_dep2)), 23512019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU32(0))); 23522019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 23532019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cond == 4 + 1) { /* cc == 1,3 -> result is not zero */ 23542019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, binop(Iop_CmpNE32, 23552019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_Add32, 23562019a976f07ff418dde2dfc7cc74667ef66d7764sewardj unop(Iop_64to32, cc_dep1), 23572019a976f07ff418dde2dfc7cc74667ef66d7764sewardj unop(Iop_64to32, cc_dep2)), 23582019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU32(0))); 23592019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 23602019a976f07ff418dde2dfc7cc74667ef66d7764sewardj goto missed; 23612019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 23622019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 23632019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* S390_CC_OP_SET */ 23642019a976f07ff418dde2dfc7cc74667ef66d7764sewardj if (cc_op == S390_CC_OP_SET) { 23652019a976f07ff418dde2dfc7cc74667ef66d7764sewardj /* cc_dep1 is the condition code 23662019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 23672019a976f07ff418dde2dfc7cc74667ef66d7764sewardj Return 1, if ((cond << cc_dep1) & 0x8) != 0 */ 23682019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 23692019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return unop(Iop_1Uto32, 23702019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_CmpNE64, 23712019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_And64, 23722019a976f07ff418dde2dfc7cc74667ef66d7764sewardj binop(Iop_Shl64, cond_expr, 23732019a976f07ff418dde2dfc7cc74667ef66d7764sewardj unop(Iop_64to8, cc_dep1)), 23742019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(8)), 23752019a976f07ff418dde2dfc7cc74667ef66d7764sewardj mkU64(0))); 23762019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 23772019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 2378af514c044bf90048e9bb916024198f9bc5dcb3f5florian goto missed; 23792019a976f07ff418dde2dfc7cc74667ef66d7764sewardj } 23802019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 23819ec12ea8dc0876141a714f7c0411aec9bdae6cffflorian /* --------- Specialising "s390_calculate_cc" --------- */ 2382af514c044bf90048e9bb916024198f9bc5dcb3f5florian 2383af514c044bf90048e9bb916024198f9bc5dcb3f5florian if (vex_streq(function_name, "s390_calculate_cc")) { 2384af514c044bf90048e9bb916024198f9bc5dcb3f5florian IRExpr *cc_op_expr, *cc_dep1; 2385af514c044bf90048e9bb916024198f9bc5dcb3f5florian ULong cc_op; 2386af514c044bf90048e9bb916024198f9bc5dcb3f5florian 2387af514c044bf90048e9bb916024198f9bc5dcb3f5florian vassert(arity == 4); 2388af514c044bf90048e9bb916024198f9bc5dcb3f5florian 2389af514c044bf90048e9bb916024198f9bc5dcb3f5florian cc_op_expr = args[0]; 2390af514c044bf90048e9bb916024198f9bc5dcb3f5florian 2391af514c044bf90048e9bb916024198f9bc5dcb3f5florian /* The necessary requirement for all optimizations here is that 2392af514c044bf90048e9bb916024198f9bc5dcb3f5florian cc_op is constant. So check that upfront. */ 2393af514c044bf90048e9bb916024198f9bc5dcb3f5florian if (! isC64(cc_op_expr)) return NULL; 2394af514c044bf90048e9bb916024198f9bc5dcb3f5florian 2395af514c044bf90048e9bb916024198f9bc5dcb3f5florian cc_op = cc_op_expr->Iex.Const.con->Ico.U64; 2396af514c044bf90048e9bb916024198f9bc5dcb3f5florian cc_dep1 = args[1]; 2397af514c044bf90048e9bb916024198f9bc5dcb3f5florian 2398af514c044bf90048e9bb916024198f9bc5dcb3f5florian if (cc_op == S390_CC_OP_BITWISE) { 2399af514c044bf90048e9bb916024198f9bc5dcb3f5florian return unop(Iop_1Uto32, 2400af514c044bf90048e9bb916024198f9bc5dcb3f5florian binop(Iop_CmpNE64, cc_dep1, mkU64(0))); 2401af514c044bf90048e9bb916024198f9bc5dcb3f5florian } 2402af514c044bf90048e9bb916024198f9bc5dcb3f5florian 2403af514c044bf90048e9bb916024198f9bc5dcb3f5florian if (cc_op == S390_CC_OP_SET) { 2404af514c044bf90048e9bb916024198f9bc5dcb3f5florian return unop(Iop_64to32, cc_dep1); 2405af514c044bf90048e9bb916024198f9bc5dcb3f5florian } 2406af514c044bf90048e9bb916024198f9bc5dcb3f5florian 2407af514c044bf90048e9bb916024198f9bc5dcb3f5florian goto missed; 2408af514c044bf90048e9bb916024198f9bc5dcb3f5florian } 2409af514c044bf90048e9bb916024198f9bc5dcb3f5florian 2410af514c044bf90048e9bb916024198f9bc5dcb3f5florianmissed: 24112019a976f07ff418dde2dfc7cc74667ef66d7764sewardj return NULL; 24122019a976f07ff418dde2dfc7cc74667ef66d7764sewardj} 24132019a976f07ff418dde2dfc7cc74667ef66d7764sewardj 24142019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*---------------------------------------------------------------*/ 24152019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*--- end guest_s390_helpers.c ---*/ 24162019a976f07ff418dde2dfc7cc74667ef66d7764sewardj/*---------------------------------------------------------------*/ 2417