1b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* 2b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * x86 CPU test 3b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * 4b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * Copyright (c) 2003 Fabrice Bellard 5b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * 6b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * This program is free software; you can redistribute it and/or modify 7b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * it under the terms of the GNU General Public License as published by 8b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * the Free Software Foundation; either version 2 of the License, or 9b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * (at your option) any later version. 10b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * 11b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * This program is distributed in the hope that it will be useful, 12b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * but WITHOUT ANY WARRANTY; without even the implied warranty of 13b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * GNU General Public License for more details. 15b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * 16b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * You should have received a copy of the GNU General Public License 17b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * along with this program; if not, write to the Free Software 18b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov */ 20b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define _GNU_SOURCE 21b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <stdlib.h> 22b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <stdio.h> 23b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <string.h> 24b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <inttypes.h> 25b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <math.h> 26b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <signal.h> 27b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <setjmp.h> 28b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <errno.h> 29b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <sys/ucontext.h> 30b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <sys/mman.h> 31b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <asm/vm86.h> 32b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 33b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Setting this to 1 creates a very comprehensive test of 34b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov integer condition codes. */ 35b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define TEST_INTEGER_VERBOSE 1 36b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 37b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 38b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov//#define LINUX_VM86_IOPL_FIX 39b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov//#define TEST_P4_FLAGS 40b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 41b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define xglue(x, y) x ## y 42b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define glue(x, y) xglue(x, y) 43b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define stringify(s) tostring(s) 44b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define tostring(s) #s 45b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 46b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CC_C 0x0001 47b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CC_P 0x0004 48b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CC_A 0x0010 49b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CC_Z 0x0040 50b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CC_S 0x0080 51b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CC_O 0x0800 52b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 53b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define __init_call __attribute__ ((unused,__section__ (".initcall.init"))) 54b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 55b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic void *call_start __init_call = NULL; 56b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 57b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A) 58b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 59b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP add 60b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "test-i386.h" 61b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 62b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP sub 63b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "test-i386.h" 64b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 65b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP xor 66b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "test-i386.h" 67b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 68b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP and 69b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "test-i386.h" 70b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 71b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP or 72b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "test-i386.h" 73b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 74b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP cmp 75b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "test-i386.h" 76b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 77b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP adc 78b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP_CC 79b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "test-i386.h" 80b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 81b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP sbb 82b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP_CC 83b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "test-i386.h" 84b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 85b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP inc 86b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP_CC 87b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP1 88b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "test-i386.h" 89b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 90b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP dec 91b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP_CC 92b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP1 93b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "test-i386.h" 94b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 95b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP neg 96b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP_CC 97b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP1 98b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "test-i386.h" 99b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 100b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP not 101b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP_CC 102b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP1 103b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "test-i386.h" 104b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 105b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#undef CC_MASK 106b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O) 107b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 108b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP shl 109b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "test-i386-shift.h" 110b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 111b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP shr 112b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "test-i386-shift.h" 113b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 114b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP sar 115b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "test-i386-shift.h" 116b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 117b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP rol 118b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "test-i386-shift.h" 119b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 120b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP ror 121b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "test-i386-shift.h" 122b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 123b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP rcr 124b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP_CC 125b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "test-i386-shift.h" 126b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 127b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP rcl 128b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP_CC 129b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "test-i386-shift.h" 130b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 131b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP shld 132b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP_SHIFTD 133b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP_NOBYTE 134b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "test-i386-shift.h" 135b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 136b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP shrd 137b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP_SHIFTD 138b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP_NOBYTE 139b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "test-i386-shift.h" 140b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 141b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 142b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* XXX: should be more precise ? */ 143b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#undef CC_MASK 144b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CC_MASK (CC_C) 145b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 146b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP bt 147b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP_NOBYTE 148b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "test-i386-shift.h" 149b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 150b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP bts 151b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP_NOBYTE 152b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "test-i386-shift.h" 153b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 154b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP btr 155b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP_NOBYTE 156b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "test-i386-shift.h" 157b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 158b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP btc 159b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP_NOBYTE 160b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "test-i386-shift.h" 161b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 162b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 163b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* lea test (modrm support) */ 164b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define TEST_LEA(STR)\ 165b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{\ 166b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm("leal " STR ", %0"\ 167b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "=r" (res)\ 168b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\ 169b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("lea %s = %08x\n", STR, res);\ 170b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 171b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 172b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define TEST_LEA16(STR)\ 173b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{\ 174b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm(".code16 ; .byte 0x67 ; leal " STR ", %0 ; .code32"\ 175b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "=wq" (res)\ 176b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "a" (eax), "b" (ebx), "c" (ecx), "d" (edx), "S" (esi), "D" (edi));\ 177b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("lea %s = %08x\n", STR, res);\ 178b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 179b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 180b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 181b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid test_lea(void) 182b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 183b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int eax, ebx, ecx, edx, esi, edi, res; 184b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov eax = 0x0001; 185b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ebx = 0x0002; 186b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ecx = 0x0004; 187b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov edx = 0x0008; 188b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov esi = 0x0010; 189b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov edi = 0x0020; 190b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 191b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("0x4000"); 192b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 193b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("(%%eax)"); 194b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("(%%ebx)"); 195b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("(%%ecx)"); 196b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("(%%edx)"); 197b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("(%%esi)"); 198b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("(%%edi)"); 199b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 200b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("0x40(%%eax)"); 201b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("0x40(%%ebx)"); 202b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("0x40(%%ecx)"); 203b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("0x40(%%edx)"); 204b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("0x40(%%esi)"); 205b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("0x40(%%edi)"); 206b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 207b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("0x4000(%%eax)"); 208b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("0x4000(%%ebx)"); 209b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("0x4000(%%ecx)"); 210b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("0x4000(%%edx)"); 211b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("0x4000(%%esi)"); 212b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("0x4000(%%edi)"); 213b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 214b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("(%%eax, %%ecx)"); 215b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("(%%ebx, %%edx)"); 216b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("(%%ecx, %%ecx)"); 217b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("(%%edx, %%ecx)"); 218b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("(%%esi, %%ecx)"); 219b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("(%%edi, %%ecx)"); 220b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 221b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("0x40(%%eax, %%ecx)"); 222b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("0x4000(%%ebx, %%edx)"); 223b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 224b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("(%%ecx, %%ecx, 2)"); 225b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("(%%edx, %%ecx, 4)"); 226b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("(%%esi, %%ecx, 8)"); 227b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 228b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("(,%%eax, 2)"); 229b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("(,%%ebx, 4)"); 230b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("(,%%ecx, 8)"); 231b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 232b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("0x40(,%%eax, 2)"); 233b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("0x40(,%%ebx, 4)"); 234b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("0x40(,%%ecx, 8)"); 235b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 236b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 237b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("-10(%%ecx, %%ecx, 2)"); 238b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("-10(%%edx, %%ecx, 4)"); 239b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("-10(%%esi, %%ecx, 8)"); 240b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 241b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("0x4000(%%ecx, %%ecx, 2)"); 242b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("0x4000(%%edx, %%ecx, 4)"); 243b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LEA("0x4000(%%esi, %%ecx, 8)"); 244b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 245b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 246b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define TEST_JCC(JCC, v1, v2)\ 247b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{\ 248b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int res;\ 249b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm("movl $1, %0\n\t"\ 250b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "cmpl %2, %1\n\t"\ 251b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "j" JCC " 1f\n\t"\ 252b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "movl $0, %0\n\t"\ 253b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "1:\n\t"\ 254b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "=r" (res)\ 255b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "r" (v1), "r" (v2));\ 256b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("%-10s %d\n", "j" JCC, res);\ 257b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov\ 258b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm("movl $0, %0\n\t"\ 259b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "cmpl %2, %1\n\t"\ 260b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "set" JCC " %b0\n\t"\ 261b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "=r" (res)\ 262b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "r" (v1), "r" (v2));\ 263b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("%-10s %d\n", "set" JCC, res);\ 264b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov { int one = 1; \ 265b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm("movl $0x12345678, %0\n\t"\ 266b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "cmpl %2, %1\n\t"\ 267b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "cmov" JCC "l %3, %0\n\t"\ 268b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "=r" (res)\ 269b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "r" (v1), "r" (v2), "m" (one));\ 270b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("%-10s R=0x%08x\n", "cmov" JCC "l", res);\ 271b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm("movl $0x12345678, %0\n\t"\ 272b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "cmpl %2, %1\n\t"\ 273b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "cmov" JCC "w %w3, %w0\n\t"\ 274b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "=r" (res)\ 275b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "r" (v1), "r" (v2), "r" (1));\ 276b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("%-10s R=0x%08x\n", "cmov" JCC "w", res);\ 277b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } \ 278b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 279b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 280b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* various jump tests */ 281b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid test_jcc(void) 282b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 283b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("ne", 1, 1); 284b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("ne", 1, 0); 285b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 286b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("e", 1, 1); 287b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("e", 1, 0); 288b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 289b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("l", 1, 1); 290b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("l", 1, 0); 291b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("l", 1, -1); 292b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 293b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("le", 1, 1); 294b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("le", 1, 0); 295b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("le", 1, -1); 296b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 297b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("ge", 1, 1); 298b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("ge", 1, 0); 299b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("ge", -1, 1); 300b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 301b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("g", 1, 1); 302b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("g", 1, 0); 303b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("g", 1, -1); 304b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 305b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("b", 1, 1); 306b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("b", 1, 0); 307b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("b", 1, -1); 308b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 309b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("be", 1, 1); 310b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("be", 1, 0); 311b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("be", 1, -1); 312b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 313b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("ae", 1, 1); 314b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("ae", 1, 0); 315b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("ae", 1, -1); 316b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 317b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("a", 1, 1); 318b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("a", 1, 0); 319b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("a", 1, -1); 320b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 321b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 322b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("p", 1, 1); 323b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("p", 1, 0); 324b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 325b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("np", 1, 1); 326b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("np", 1, 0); 327b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 328b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("o", 0x7fffffff, 0); 329b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("o", 0x7fffffff, -1); 330b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 331b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("no", 0x7fffffff, 0); 332b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("no", 0x7fffffff, -1); 333b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 334b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("s", 0, 1); 335b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("s", 0, -1); 336b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("s", 0, 0); 337b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 338b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("ns", 0, 1); 339b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("ns", 0, -1); 340b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_JCC("ns", 0, 0); 341b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 342b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 343b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#undef CC_MASK 344b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#ifdef TEST_P4_FLAGS 345b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CC_MASK (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A) 346b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#else 347b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CC_MASK (CC_O | CC_C) 348b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 349b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 350b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP mul 351b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "test-i386-muldiv.h" 352b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 353b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP imul 354b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "test-i386-muldiv.h" 355b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 356b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid test_imulw2(int op0, int op1) 357b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 358b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int res, s1, s0, flags; 359b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov s0 = op0; 360b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov s1 = op1; 361b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov res = s0; 362b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov flags = 0; 363b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm ("push %4\n\t" 364b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "popf\n\t" 365b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "imulw %w2, %w0\n\t" 366b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "pushf\n\t" 367b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "popl %1\n\t" 368b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "=q" (res), "=g" (flags) 369b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "q" (s1), "0" (res), "1" (flags)); 370b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("%-10s A=%08x B=%08x R=%08x CC=%04x\n", 371b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "imulw", s0, s1, res, flags & CC_MASK); 372b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 373b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 374b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid test_imull2(int op0, int op1) 375b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 376b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int res, s1, s0, flags; 377b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov s0 = op0; 378b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov s1 = op1; 379b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov res = s0; 380b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov flags = 0; 381b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm ("push %4\n\t" 382b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "popf\n\t" 383b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "imull %2, %0\n\t" 384b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "pushf\n\t" 385b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "popl %1\n\t" 386b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "=q" (res), "=g" (flags) 387b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "q" (s1), "0" (res), "1" (flags)); 388b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("%-10s A=%08x B=%08x R=%08x CC=%04x\n", 389b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "imull", s0, s1, res, flags & CC_MASK); 390b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 391b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 392b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define TEST_IMUL_IM(size, size1, op0, op1)\ 393b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{\ 394b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int res, flags;\ 395b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov flags = 0;\ 396b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov res = 0;\ 397b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm ("push %3\n\t"\ 398b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "popf\n\t"\ 399b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "imul" size " $" #op0 ", %" size1 "2, %" size1 "0\n\t" \ 400b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "pushf\n\t"\ 401b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "popl %1\n\t"\ 402b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "=r" (res), "=g" (flags)\ 403b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "r" (op1), "1" (flags), "0" (res));\ 404b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("%-10s A=%08x B=%08x R=%08x CC=%04x\n",\ 405b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "imul" size, op0, op1, res, flags & CC_MASK);\ 406b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 407b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 408b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 409b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#undef CC_MASK 410b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define CC_MASK (0) 411b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 412b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP div 413b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "test-i386-muldiv.h" 414b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 415b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define OP idiv 416b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include "test-i386-muldiv.h" 417b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 418b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid test_mul(void) 419b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 420b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_imulb(0x1234561d, 4); 421b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_imulb(3, -4); 422b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_imulb(0x80, 0x80); 423b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_imulb(0x10, 0x10); 424b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 425b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_imulw(0, 0, 0); 426b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_imulw(0, 0xFF, 0xFF); 427b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_imulw(0, 0xFF, 0x100); 428b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_imulw(0, 0x1234001d, 45); 429b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_imulw(0, 23, -45); 430b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_imulw(0, 0x8000, 0x8000); 431b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_imulw(0, 0x100, 0x100); 432b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 433b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_imull(0, 0, 0); 434b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_imull(0, 0xFFFF, 0xFFFF); 435b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_imull(0, 0xFFFF, 0x10000); 436b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_imull(0, 0x1234001d, 45); 437b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_imull(0, 23, -45); 438b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_imull(0, 0x80000000, 0x80000000); 439b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_imull(0, 0x10000, 0x10000); 440b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 441b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_mulb(0x1234561d, 4); 442b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_mulb(3, -4); 443b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_mulb(0x80, 0x80); 444b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_mulb(0x10, 0x10); 445b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 446b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_mulw(0, 0x1234001d, 45); 447b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_mulw(0, 23, -45); 448b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_mulw(0, 0x8000, 0x8000); 449b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_mulw(0, 0x100, 0x100); 450b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 451b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_mull(0, 0x1234001d, 45); 452b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_mull(0, 23, -45); 453b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_mull(0, 0x80000000, 0x80000000); 454b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_mull(0, 0x10000, 0x10000); 455b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 456b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_imulw2(0x1234001d, 45); 457b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_imulw2(23, -45); 458b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_imulw2(0x8000, 0x8000); 459b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_imulw2(0x100, 0x100); 460b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 461b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_imull2(0x1234001d, 45); 462b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_imull2(23, -45); 463b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_imull2(0x80000000, 0x80000000); 464b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_imull2(0x10000, 0x10000); 465b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 466b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_IMUL_IM("w", "w", 45, 0x1234); 467b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_IMUL_IM("w", "w", -45, 23); 468b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_IMUL_IM("w", "w", 0x8000, 0x80000000); 469b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_IMUL_IM("w", "w", 0x7fff, 0x1000); 470b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 471b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_IMUL_IM("l", "", 45, 0x1234); 472b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_IMUL_IM("l", "", -45, 23); 473b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_IMUL_IM("l", "", 0x8000, 0x80000000); 474b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_IMUL_IM("l", "", 0x7fff, 0x1000); 475b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 476b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_idivb(0x12341678, 0x127e); 477b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_idivb(0x43210123, -5); 478b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_idivb(0x12340004, -1); 479b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 480b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_idivw(0, 0x12345678, 12347); 481b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_idivw(0, -23223, -45); 482b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_idivw(0, 0x12348000, -1); 483b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_idivw(0x12343, 0x12345678, 0x81238567); 484b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 485b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_idivl(0, 0x12345678, 12347); 486b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_idivl(0, -233223, -45); 487b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_idivl(0, 0x80000000, -1); 488b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_idivl(0x12343, 0x12345678, 0x81234567); 489b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 490b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_divb(0x12341678, 0x127e); 491b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_divb(0x43210123, -5); 492b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_divb(0x12340004, -1); 493b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 494b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_divw(0, 0x12345678, 12347); 495b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_divw(0, -23223, -45); 496b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_divw(0, 0x12348000, -1); 497b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_divw(0x12343, 0x12345678, 0x81238567); 498b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 499b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_divl(0, 0x12345678, 12347); 500b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_divl(0, -233223, -45); 501b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_divl(0, 0x80000000, -1); 502b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_divl(0x12343, 0x12345678, 0x81234567); 503b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 504b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 505b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define TEST_BSX(op, size, op0)\ 506b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{\ 507b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int res, val, resz;\ 508b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov val = op0;\ 509b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm("xorl %1, %1\n\t"\ 510b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "movl $0x12345678, %0\n\t"\ 511b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov #op " %" size "2, %" size "0\n\t" \ 512b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "setz %b1" \ 513b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "=r" (res), "=q" (resz)\ 514b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "r" (val));\ 515b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("%-10s A=%08x R=%08x %d\n", #op, val, res, resz);\ 516b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 517b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 518b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid test_bsx(void) 519b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 520b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BSX(bsrw, "w", 0); 521b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BSX(bsrw, "w", 0x12340128); 522b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BSX(bsrl, "", 0); 523b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BSX(bsrl, "", 0x00340128); 524b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BSX(bsfw, "w", 0); 525b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BSX(bsfw, "w", 0x12340128); 526b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BSX(bsfl, "", 0); 527b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BSX(bsfl, "", 0x00340128); 528b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 529b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 530b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/**********************************************/ 531b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 532b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid test_fops(double a, double b) 533b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 534b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("a=%f b=%f a+b=%f\n", a, b, a + b); 535b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("a=%f b=%f a-b=%f\n", a, b, a - b); 536b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("a=%f b=%f a*b=%f\n", a, b, a * b); 537b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("a=%f b=%f a/b=%f\n", a, b, a / b); 538b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("a=%f b=%f fmod(a, b)=%f\n", a, b, fmod(a, b)); 539b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("a=%f sqrt(a)=%f\n", a, sqrt(a)); 540b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("a=%f sin(a)=%f\n", a, sin(a)); 541b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("a=%f cos(a)=%f\n", a, cos(a)); 542b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("a=%f tan(a)=%f\n", a, tan(a)); 543b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("a=%f log(a)=%f\n", a, log(a)); 544b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("a=%f exp(a)=%f\n", a, exp(a)); 545b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("a=%f b=%f atan2(a, b)=%f\n", a, b, atan2(a, b)); 546b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* just to test some op combining */ 547b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("a=%f asin(sin(a))=%f\n", a, asin(sin(a))); 548b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("a=%f acos(cos(a))=%f\n", a, acos(cos(a))); 549b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("a=%f atan(tan(a))=%f\n", a, atan(tan(a))); 550b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 551b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 552b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid test_fcmp(double a, double b) 553b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 554b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("(%f<%f)=%d\n", 555b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov a, b, a < b); 556b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("(%f<=%f)=%d\n", 557b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov a, b, a <= b); 558b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("(%f==%f)=%d\n", 559b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov a, b, a == b); 560b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("(%f>%f)=%d\n", 561b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov a, b, a > b); 562b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("(%f<=%f)=%d\n", 563b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov a, b, a >= b); 564b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov { 565b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unsigned int eflags; 566b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* test f(u)comi instruction */ 567b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm("fcomi %2, %1\n" 568b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "pushf\n" 569b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "pop %0\n" 570b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "=r" (eflags) 571b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "t" (a), "u" (b)); 572b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("fcomi(%f %f)=%08x\n", a, b, eflags & (CC_Z | CC_P | CC_C)); 573b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 574b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 575b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 576b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid test_fcvt(double a) 577b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 578b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov float fa; 579b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov long double la; 580b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int16_t fpuc; 581b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int i; 582b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int64_t lla; 583b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int ia; 584b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int16_t wa; 585b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov double ra; 586b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 587b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov fa = a; 588b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov la = a; 589b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("(float)%f = %f\n", a, fa); 590b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("(long double)%f = %Lf\n", a, la); 591b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("a=%016Lx\n", *(long long *)&a); 592b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("la=%016Lx %04x\n", *(long long *)&la, 593b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *(unsigned short *)((char *)(&la) + 8)); 594b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 595b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* test all roundings */ 596b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("fstcw %0" : "=m" (fpuc)); 597b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for(i=0;i<4;i++) { 598b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int16_t tmp = (fpuc & ~0x0c00) | (i << 10); 599b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("fldcw %0" : : "m" (tmp)); 600b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("fist %0" : "=m" (wa) : "t" (a)); 601b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("fistl %0" : "=m" (ia) : "t" (a)); 602b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("fistpll %0" : "=m" (lla) : "t" (a) : "st"); 603b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("frndint ; fstl %0" : "=m" (ra) : "t" (a)); 604b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("fldcw %0" : : "m" (fpuc)); 605b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("(short)a = %d\n", wa); 606b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("(int)a = %d\n", ia); 607b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("(int64_t)a = %Ld\n", lla); 608b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("rint(a) = %f\n", ra); 609b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 610b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 611b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 612b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define TEST(N) \ 613b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm("fld" #N : "=t" (a)); \ 614b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("fld" #N "= %f\n", a); 615b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 616b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid test_fconst(void) 617b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 618b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov double a; 619b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST(1); 620b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST(l2t); 621b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST(l2e); 622b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST(pi); 623b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST(lg2); 624b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST(ln2); 625b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST(z); 626b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 627b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 628b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid test_fbcd(double a) 629b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 630b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unsigned short bcd[5]; 631b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov double b; 632b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 633b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm("fbstp %0" : "=m" (bcd[0]) : "t" (a) : "st"); 634b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm("fbld %1" : "=t" (b) : "m" (bcd[0])); 635b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("a=%f bcd=%04x%04x%04x%04x%04x b=%f\n", 636b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov a, bcd[4], bcd[3], bcd[2], bcd[1], bcd[0], b); 637b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 638b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 639b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define TEST_ENV(env, save, restore)\ 640b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{\ 641b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov memset((env), 0xaa, sizeof(*(env)));\ 642b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for(i=0;i<5;i++)\ 643b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("fldl %0" : : "m" (dtab[i]));\ 644b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm(save " %0\n" : : "m" (*(env)));\ 645b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm(restore " %0\n": : "m" (*(env)));\ 646b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for(i=0;i<5;i++)\ 647b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("fstpl %0" : "=m" (rtab[i]));\ 648b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for(i=0;i<5;i++)\ 649b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("res[%d]=%f\n", i, rtab[i]);\ 650b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("fpuc=%04x fpus=%04x fptag=%04x\n",\ 651b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (env)->fpuc,\ 652b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (env)->fpus & 0xff00,\ 653b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (env)->fptag);\ 654b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 655b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 656b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid test_fenv(void) 657b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 658b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov struct __attribute__((packed)) { 659b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov uint16_t fpuc; 660b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov uint16_t dummy1; 661b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov uint16_t fpus; 662b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov uint16_t dummy2; 663b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov uint16_t fptag; 664b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov uint16_t dummy3; 665b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov uint32_t ignored[4]; 666b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov long double fpregs[8]; 667b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } float_env32; 668b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov struct __attribute__((packed)) { 669b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov uint16_t fpuc; 670b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov uint16_t fpus; 671b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov uint16_t fptag; 672b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov uint16_t ignored[4]; 673b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov long double fpregs[8]; 674b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } float_env16; 675b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov double dtab[8]; 676b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov double rtab[8]; 677b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int i; 678b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 679b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for(i=0;i<8;i++) 680b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov dtab[i] = i + 1; 681b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 682b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_ENV(&float_env16, "data16 fnstenv", "data16 fldenv"); 683b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_ENV(&float_env16, "data16 fnsave", "data16 frstor"); 684b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_ENV(&float_env32, "fnstenv", "fldenv"); 685b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_ENV(&float_env32, "fnsave", "frstor"); 686b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 687b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* test for ffree */ 688b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for(i=0;i<5;i++) 689b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("fldl %0" : : "m" (dtab[i])); 690b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile("ffree %st(2)"); 691b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("fnstenv %0\n" : : "m" (float_env32)); 692b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("fninit"); 693b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("fptag=%04x\n", float_env32.fptag); 694b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 695b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 696b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 697b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define TEST_FCMOV(a, b, eflags, CC)\ 698b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{\ 699b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov double res;\ 700b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm("push %3\n"\ 701b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "popf\n"\ 702b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "fcmov" CC " %2, %0\n"\ 703b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "=t" (res)\ 704b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "0" (a), "u" (b), "g" (eflags));\ 705b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("fcmov%s eflags=0x%04x-> %f\n", \ 706b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov CC, eflags, res);\ 707b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 708b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 709b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid test_fcmov(void) 710b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 711b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov double a, b; 712b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int eflags, i; 713b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 714b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov a = 1.0; 715b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov b = 2.0; 716b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for(i = 0; i < 4; i++) { 717b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov eflags = 0; 718b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (i & 1) 719b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov eflags |= CC_C; 720b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (i & 2) 721b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov eflags |= CC_Z; 722b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_FCMOV(a, b, eflags, "b"); 723b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_FCMOV(a, b, eflags, "e"); 724b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_FCMOV(a, b, eflags, "be"); 725b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_FCMOV(a, b, eflags, "nb"); 726b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_FCMOV(a, b, eflags, "ne"); 727b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_FCMOV(a, b, eflags, "nbe"); 728b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 729b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_FCMOV(a, b, 0, "u"); 730b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_FCMOV(a, b, CC_P, "u"); 731b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_FCMOV(a, b, 0, "nu"); 732b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_FCMOV(a, b, CC_P, "nu"); 733b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 734b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 735b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid test_floats(void) 736b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 737b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_fops(2, 3); 738b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_fops(1.4, -5); 739b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_fcmp(2, -1); 740b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_fcmp(2, 2); 741b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_fcmp(2, 3); 742b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_fcvt(0.5); 743b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_fcvt(-0.5); 744b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_fcvt(1.0/7.0); 745b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_fcvt(-1.0/9.0); 746b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_fcvt(32768); 747b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_fcvt(-1e20); 748b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_fconst(); 749b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // REINSTATE (maybe): test_fbcd(1234567890123456); 750b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // REINSTATE (maybe): test_fbcd(-123451234567890); 751b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // REINSTATE: test_fenv(); 752b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // REINSTATE: test_fcmov(); 753b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 754b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 755b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/**********************************************/ 756b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if 0 757b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 758b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define TEST_BCD(op, op0, cc_in, cc_mask)\ 759b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{\ 760b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int res, flags;\ 761b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov res = op0;\ 762b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov flags = cc_in;\ 763b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm ("push %3\n\t"\ 764b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "popf\n\t"\ 765b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov #op "\n\t"\ 766b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "pushf\n\t"\ 767b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "popl %1\n\t"\ 768b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "=a" (res), "=g" (flags)\ 769b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "0" (res), "1" (flags));\ 770b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("%-10s A=%08x R=%08x CCIN=%04x CC=%04x\n",\ 771b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov #op, op0, res, cc_in, flags & cc_mask);\ 772b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 773b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 774b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid test_bcd(void) 775b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 776b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(daa, 0x12340503, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); 777b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(daa, 0x12340506, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); 778b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(daa, 0x12340507, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); 779b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(daa, 0x12340559, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); 780b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(daa, 0x12340560, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); 781b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(daa, 0x1234059f, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); 782b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(daa, 0x123405a0, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); 783b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(daa, 0x12340503, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A)); 784b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(daa, 0x12340506, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A)); 785b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(daa, 0x12340503, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A)); 786b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(daa, 0x12340506, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A)); 787b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(daa, 0x12340503, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); 788b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(daa, 0x12340506, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); 789b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 790b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(das, 0x12340503, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); 791b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(das, 0x12340506, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); 792b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(das, 0x12340507, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); 793b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(das, 0x12340559, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); 794b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(das, 0x12340560, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); 795b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(das, 0x1234059f, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); 796b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(das, 0x123405a0, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); 797b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(das, 0x12340503, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A)); 798b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(das, 0x12340506, 0, (CC_C | CC_P | CC_Z | CC_S | CC_A)); 799b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(das, 0x12340503, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A)); 800b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(das, 0x12340506, CC_C, (CC_C | CC_P | CC_Z | CC_S | CC_A)); 801b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(das, 0x12340503, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); 802b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(das, 0x12340506, CC_C | CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_A)); 803b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 804b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(aaa, 0x12340205, CC_A, (CC_C | CC_A)); 805b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(aaa, 0x12340306, CC_A, (CC_C | CC_A)); 806b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(aaa, 0x1234040a, CC_A, (CC_C | CC_A)); 807b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(aaa, 0x123405fa, CC_A, (CC_C | CC_A)); 808b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(aaa, 0x12340205, 0, (CC_C | CC_A)); 809b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(aaa, 0x12340306, 0, (CC_C | CC_A)); 810b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(aaa, 0x1234040a, 0, (CC_C | CC_A)); 811b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(aaa, 0x123405fa, 0, (CC_C | CC_A)); 812b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 813b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(aas, 0x12340205, CC_A, (CC_C | CC_A)); 814b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(aas, 0x12340306, CC_A, (CC_C | CC_A)); 815b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(aas, 0x1234040a, CC_A, (CC_C | CC_A)); 816b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(aas, 0x123405fa, CC_A, (CC_C | CC_A)); 817b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(aas, 0x12340205, 0, (CC_C | CC_A)); 818b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(aas, 0x12340306, 0, (CC_C | CC_A)); 819b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(aas, 0x1234040a, 0, (CC_C | CC_A)); 820b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(aas, 0x123405fa, 0, (CC_C | CC_A)); 821b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 822b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(aam, 0x12340547, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)); 823b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_BCD(aad, 0x12340407, CC_A, (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A)); 824b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 825b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif /* 0 */ 826b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 827b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define TEST_XCHG(op, size, opconst)\ 828b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{\ 829b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int op0, op1;\ 830b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov op0 = 0x12345678;\ 831b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov op1 = 0xfbca7654;\ 832b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm(#op " %" size "0, %" size "1" \ 833b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "=q" (op0), opconst (op1) \ 834b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "0" (op0), "1" (op1));\ 835b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("%-10s A=%08x B=%08x\n",\ 836b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov #op, op0, op1);\ 837b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 838b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 839b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define TEST_CMPXCHG(op, size, opconst, eax)\ 840b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{\ 841b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int op0, op1;\ 842b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov op0 = 0x12345678;\ 843b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov op1 = 0xfbca7654;\ 844b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm(#op " %" size "0, %" size "1" \ 845b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "=q" (op0), opconst (op1) \ 846b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "0" (op0), "1" (op1), "a" (eax));\ 847b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("%-10s EAX=%08x A=%08x C=%08x\n",\ 848b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov #op, eax, op0, op1);\ 849b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 850b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 851b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid test_xchg(void) 852b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 853b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_XCHG(xchgl, "", "=q"); 854b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_XCHG(xchgw, "w", "=q"); 855b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_XCHG(xchgb, "b", "=q"); 856b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 857b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_XCHG(xchgl, "", "=m"); 858b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_XCHG(xchgw, "w", "=m"); 859b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_XCHG(xchgb, "b", "=m"); 860b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 861b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if 0 862b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_XCHG(xaddl, "", "=q"); 863b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_XCHG(xaddw, "w", "=q"); 864b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_XCHG(xaddb, "b", "=q"); 865b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 866b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov { 867b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int res; 868b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov res = 0x12345678; 869b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm("xaddl %1, %0" : "=r" (res) : "0" (res)); 870b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("xaddl same res=%08x\n", res); 871b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 872b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 873b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_XCHG(xaddl, "", "=m"); 874b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_XCHG(xaddw, "w", "=m"); 875b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_XCHG(xaddb, "b", "=m"); 876b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 877b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_CMPXCHG(cmpxchgl, "", "=q", 0xfbca7654); 878b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_CMPXCHG(cmpxchgw, "w", "=q", 0xfbca7654); 879b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_CMPXCHG(cmpxchgb, "b", "=q", 0xfbca7654); 880b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 881b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_CMPXCHG(cmpxchgl, "", "=q", 0xfffefdfc); 882b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_CMPXCHG(cmpxchgw, "w", "=q", 0xfffefdfc); 883b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_CMPXCHG(cmpxchgb, "b", "=q", 0xfffefdfc); 884b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 885b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_CMPXCHG(cmpxchgl, "", "=m", 0xfbca7654); 886b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_CMPXCHG(cmpxchgw, "w", "=m", 0xfbca7654); 887b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_CMPXCHG(cmpxchgb, "b", "=m", 0xfbca7654); 888b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 889b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_CMPXCHG(cmpxchgl, "", "=m", 0xfffefdfc); 890b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_CMPXCHG(cmpxchgw, "w", "=m", 0xfffefdfc); 891b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_CMPXCHG(cmpxchgb, "b", "=m", 0xfffefdfc); 892b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if 0 893b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov { 894b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov uint64_t op0, op1, op2; 895b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int i, eflags; 896b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 897b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for(i = 0; i < 2; i++) { 898b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov op0 = 0x123456789abcd; 899b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (i == 0) 900b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov op1 = 0xfbca765423456; 901b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov else 902b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov op1 = op0; 903b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov op2 = 0x6532432432434; 904b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm("cmpxchg8b %1\n" 905b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "pushf\n" 906b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "popl %2\n" 907b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "=A" (op0), "=m" (op1), "=g" (eflags) 908b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "0" (op0), "m" (op1), "b" ((int)op2), "c" ((int)(op2 >> 32))); 909b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("cmpxchg8b: op0=%016llx op1=%016llx CC=%02x\n", 910b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov op0, op1, eflags & CC_Z); 911b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 912b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 913b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 914b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 915b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 916b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/**********************************************/ 917b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* segmentation tests */ 918b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if 0 919b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <asm/ldt.h> 920b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <linux/unistd.h> 921b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#include <linux/version.h> 922b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 923b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov_syscall3(int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount) 924b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 925b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 66) 926b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define modify_ldt_ldt_s user_desc 927b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 928b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 929b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovuint8_t seg_data1[4096]; 930b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovuint8_t seg_data2[4096]; 931b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 932b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define MK_SEL(n) (((n) << 3) | 7) 933b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 934b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define TEST_LR(op, size, seg, mask)\ 935b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{\ 936b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int res, res2;\ 937b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov res = 0x12345678;\ 938b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm (op " %" size "2, %" size "0\n" \ 939b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "movl $0, %1\n"\ 940b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "jnz 1f\n"\ 941b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "movl $1, %1\n"\ 942b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "1:\n"\ 943b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "=r" (res), "=r" (res2) : "m" (seg), "0" (res));\ 944b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf(op ": Z=%d %08x\n", res2, res & ~(mask));\ 945b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 946b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 947b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* NOTE: we use Linux modify_ldt syscall */ 948b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid test_segs(void) 949b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 950b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov struct modify_ldt_ldt_s ldt; 951b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov long long ldt_table[3]; 952b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int res, res2; 953b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char tmp; 954b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov struct { 955b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov uint32_t offset; 956b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov uint16_t seg; 957b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } __attribute__((packed)) segoff; 958b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 959b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldt.entry_number = 1; 960b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldt.base_addr = (unsigned long)&seg_data1; 961b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldt.limit = (sizeof(seg_data1) + 0xfff) >> 12; 962b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldt.seg_32bit = 1; 963b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldt.contents = MODIFY_LDT_CONTENTS_DATA; 964b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldt.read_exec_only = 0; 965b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldt.limit_in_pages = 1; 966b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldt.seg_not_present = 0; 967b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldt.useable = 1; 968b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */ 969b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 970b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldt.entry_number = 2; 971b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldt.base_addr = (unsigned long)&seg_data2; 972b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldt.limit = (sizeof(seg_data2) + 0xfff) >> 12; 973b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldt.seg_32bit = 1; 974b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldt.contents = MODIFY_LDT_CONTENTS_DATA; 975b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldt.read_exec_only = 0; 976b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldt.limit_in_pages = 1; 977b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldt.seg_not_present = 0; 978b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldt.useable = 1; 979b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */ 980b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 981b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov modify_ldt(0, &ldt_table, sizeof(ldt_table)); /* read ldt entries */ 982b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if 0 983b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov { 984b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int i; 985b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for(i=0;i<3;i++) 986b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("%d: %016Lx\n", i, ldt_table[i]); 987b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 988b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 989b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* do some tests with fs or gs */ 990b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("movl %0, %%fs" : : "r" (MK_SEL(1))); 991b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 992b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov seg_data1[1] = 0xaa; 993b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov seg_data2[1] = 0x55; 994b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 995b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("fs movzbl 0x1, %0" : "=r" (res)); 996b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("FS[1] = %02x\n", res); 997b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 998b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("pushl %%gs\n" 999b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "movl %1, %%gs\n" 1000b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "gs movzbl 0x1, %0\n" 1001b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "popl %%gs\n" 1002b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "=r" (res) 1003b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "r" (MK_SEL(2))); 1004b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("GS[1] = %02x\n", res); 1005b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1006b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* tests with ds/ss (implicit segment case) */ 1007b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov tmp = 0xa5; 1008b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("pushl %%ebp\n\t" 1009b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "pushl %%ds\n\t" 1010b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "movl %2, %%ds\n\t" 1011b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "movl %3, %%ebp\n\t" 1012b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "movzbl 0x1, %0\n\t" 1013b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "movzbl (%%ebp), %1\n\t" 1014b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "popl %%ds\n\t" 1015b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "popl %%ebp\n\t" 1016b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "=r" (res), "=r" (res2) 1017b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "r" (MK_SEL(1)), "r" (&tmp)); 1018b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("DS[1] = %02x\n", res); 1019b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("SS[tmp] = %02x\n", res2); 1020b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1021b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov segoff.seg = MK_SEL(2); 1022b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov segoff.offset = 0xabcdef12; 1023b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile("lfs %2, %0\n\t" 1024b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "movl %%fs, %1\n\t" 1025b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "=r" (res), "=g" (res2) 1026b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "m" (segoff)); 1027b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("FS:reg = %04x:%08x\n", res2, res); 1028b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1029b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LR("larw", "w", MK_SEL(2), 0x0100); 1030b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LR("larl", "", MK_SEL(2), 0x0100); 1031b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LR("lslw", "w", MK_SEL(2), 0); 1032b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LR("lsll", "", MK_SEL(2), 0); 1033b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1034b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LR("larw", "w", 0xfff8, 0); 1035b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LR("larl", "", 0xfff8, 0); 1036b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LR("lslw", "w", 0xfff8, 0); 1037b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_LR("lsll", "", 0xfff8, 0); 1038b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 1039b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 1040b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1041b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if 0 1042b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* 16 bit code test */ 1043b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovextern char code16_start, code16_end; 1044b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovextern char code16_func1; 1045b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovextern char code16_func2; 1046b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovextern char code16_func3; 1047b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1048b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid test_code16(void) 1049b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 1050b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov struct modify_ldt_ldt_s ldt; 1051b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int res, res2; 1052b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1053b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* build a code segment */ 1054b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldt.entry_number = 1; 1055b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldt.base_addr = (unsigned long)&code16_start; 1056b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldt.limit = &code16_end - &code16_start; 1057b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldt.seg_32bit = 0; 1058b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldt.contents = MODIFY_LDT_CONTENTS_CODE; 1059b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldt.read_exec_only = 0; 1060b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldt.limit_in_pages = 0; 1061b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldt.seg_not_present = 0; 1062b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldt.useable = 1; 1063b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */ 1064b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1065b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* call the first function */ 1066b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("lcall %1, %2" 1067b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "=a" (res) 1068b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "i" (MK_SEL(1)), "i" (&code16_func1): "memory", "cc"); 1069b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("func1() = 0x%08x\n", res); 1070b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("lcall %2, %3" 1071b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "=a" (res), "=c" (res2) 1072b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "i" (MK_SEL(1)), "i" (&code16_func2): "memory", "cc"); 1073b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("func2() = 0x%08x spdec=%d\n", res, res2); 1074b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("lcall %1, %2" 1075b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "=a" (res) 1076b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "i" (MK_SEL(1)), "i" (&code16_func3): "memory", "cc"); 1077b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("func3() = 0x%08x\n", res); 1078b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 1079b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 1080b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1081b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovextern char func_lret32; 1082b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovextern char func_iret32; 1083b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1084b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid test_misc(void) 1085b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 1086b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov char table[256]; 1087b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int res, i; 1088b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1089b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if 0 1090b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // REINSTATE 1091b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for(i=0;i<256;i++) table[i] = 256 - i; 1092b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov res = 0x12345678; 1093b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm ("xlat" : "=a" (res) : "b" (table), "0" (res)); 1094b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("xlat: EAX=%08x\n", res); 1095b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 1096b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if 0 1097b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // REINSTATE 1098b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("pushl %%cs ; call %1" 1099b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "=a" (res) 1100b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "m" (func_lret32): "memory", "cc"); 1101b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("func_lret32=%x\n", res); 1102b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1103b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("pushfl ; pushl %%cs ; call %1" 1104b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "=a" (res) 1105b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "m" (func_iret32): "memory", "cc"); 1106b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("func_iret32=%x\n", res); 1107b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 1108b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* specific popl test */ 1109b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("pushl $12345432 ; pushl $0x9abcdef ; popl (%%esp) ; popl %0" 1110b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "=g" (res)); 1111b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("popl esp=%x\n", res); 1112b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if 0 1113b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // REINSTATE 1114b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* specific popw test */ 1115b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("pushl $12345432 ; pushl $0x9abcdef ; popw (%%esp) ; addl $2, %%esp ; popl %0" 1116b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "=g" (res)); 1117b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("popw esp=%x\n", res); 1118b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 1119b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 1120b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1121b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovuint8_t str_buffer[4096]; 1122b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1123b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define TEST_STRING1(OP, size, DF, REP)\ 1124b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{\ 1125b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int esi, edi, eax, ecx, eflags;\ 1126b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov\ 1127b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov esi = (long)(str_buffer + sizeof(str_buffer) / 2);\ 1128b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov edi = (long)(str_buffer + sizeof(str_buffer) / 2) + 16;\ 1129b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov eax = 0x12345678;\ 1130b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ecx = 17;\ 1131b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov\ 1132b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("pushl $0\n\t"\ 1133b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "popf\n\t"\ 1134b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov DF "\n\t"\ 1135b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov REP #OP size "\n\t"\ 1136b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "cld\n\t"\ 1137b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "pushf\n\t"\ 1138b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "popl %4\n\t"\ 1139b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "=S" (esi), "=D" (edi), "=a" (eax), "=c" (ecx), "=g" (eflags)\ 1140b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "0" (esi), "1" (edi), "2" (eax), "3" (ecx));\ 1141b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("%-10s ESI=%08x EDI=%08x EAX=%08x ECX=%08x EFL=%04x\n",\ 1142b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov REP #OP size, esi, edi, eax, ecx,\ 1143b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov eflags & (CC_C | CC_P | CC_Z | CC_S | CC_O | CC_A));\ 1144b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 1145b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1146b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define TEST_STRING(OP, REP)\ 1147b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_STRING1(OP, "b", "", REP);\ 1148b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_STRING1(OP, "w", "", REP);\ 1149b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_STRING1(OP, "l", "", REP);\ 1150b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_STRING1(OP, "b", "std", REP);\ 1151b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_STRING1(OP, "w", "std", REP);\ 1152b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_STRING1(OP, "l", "std", REP) 1153b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1154b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid test_string(void) 1155b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 1156b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int i; 1157b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for(i = 0;i < sizeof(str_buffer); i++) 1158b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov str_buffer[i] = i + 0x56; 1159b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_STRING(stos, ""); 1160b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_STRING(stos, "rep "); 1161b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // REINSTATE: TEST_STRING(lods, ""); /* to verify stos */ 1162b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // REINSTATE: TEST_STRING(lods, "rep "); 1163b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_STRING(movs, ""); 1164b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_STRING(movs, "rep "); 1165b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // REINSTATE: TEST_STRING(lods, ""); /* to verify stos */ 1166b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1167b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* XXX: better tests */ 1168b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_STRING(scas, ""); 1169b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // REINSTATE: TEST_STRING(scas, "repz "); 1170b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_STRING(scas, "repnz "); 1171b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // REINSTATE: TEST_STRING(cmps, ""); 1172b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov TEST_STRING(cmps, "repz "); 1173b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // REINSTATE: TEST_STRING(cmps, "repnz "); 1174b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 1175b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1176b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* VM86 test */ 1177b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if 0 1178b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic inline void set_bit(uint8_t *a, unsigned int bit) 1179b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 1180b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov a[bit / 8] |= (1 << (bit % 8)); 1181b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 1182b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1183b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic inline uint8_t *seg_to_linear(unsigned int seg, unsigned int reg) 1184b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 1185b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return (uint8_t *)((seg << 4) + (reg & 0xffff)); 1186b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 1187b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1188b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic inline void pushw(struct vm86_regs *r, int val) 1189b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 1190b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov r->esp = (r->esp & ~0xffff) | ((r->esp - 2) & 0xffff); 1191b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *(uint16_t *)seg_to_linear(r->ss, r->esp) = val; 1192b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 1193b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1194b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#undef __syscall_return 1195b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define __syscall_return(type, res) \ 1196b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovdo { \ 1197b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return (type) (res); \ 1198b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} while (0) 1199b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1200b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov_syscall2(int, vm86, int, func, struct vm86plus_struct *, v86) 1201b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1202b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovextern char vm86_code_start; 1203b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovextern char vm86_code_end; 1204b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1205b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VM86_CODE_CS 0x100 1206b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define VM86_CODE_IP 0x100 1207b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1208b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid test_vm86(void) 1209b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 1210b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov struct vm86plus_struct ctx; 1211b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov struct vm86_regs *r; 1212b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov uint8_t *vm86_mem; 1213b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int seg, ret; 1214b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1215b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov vm86_mem = mmap((void *)0x00000000, 0x110000, 1216b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov PROT_WRITE | PROT_READ | PROT_EXEC, 1217b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0); 1218b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (vm86_mem == MAP_FAILED) { 1219b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("ERROR: could not map vm86 memory"); 1220b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return; 1221b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1222b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov memset(&ctx, 0, sizeof(ctx)); 1223b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1224b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* init basic registers */ 1225b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov r = &ctx.regs; 1226b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov r->eip = VM86_CODE_IP; 1227b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov r->esp = 0xfffe; 1228b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov seg = VM86_CODE_CS; 1229b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov r->cs = seg; 1230b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov r->ss = seg; 1231b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov r->ds = seg; 1232b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov r->es = seg; 1233b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov r->fs = seg; 1234b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov r->gs = seg; 1235b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov r->eflags = VIF_MASK; 1236b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1237b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* move code to proper address. We use the same layout as a .com 1238b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov dos program. */ 1239b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov memcpy(vm86_mem + (VM86_CODE_CS << 4) + VM86_CODE_IP, 1240b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov &vm86_code_start, &vm86_code_end - &vm86_code_start); 1241b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1242b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* mark int 0x21 as being emulated */ 1243b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov set_bit((uint8_t *)&ctx.int_revectored, 0x21); 1244b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1245b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for(;;) { 1246b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ret = vm86(VM86_ENTER, &ctx); 1247b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov switch(VM86_TYPE(ret)) { 1248b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case VM86_INTx: 1249b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov { 1250b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int int_num, ah, v; 1251b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1252b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int_num = VM86_ARG(ret); 1253b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (int_num != 0x21) 1254b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov goto unknown_int; 1255b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ah = (r->eax >> 8) & 0xff; 1256b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov switch(ah) { 1257b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case 0x00: /* exit */ 1258b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov goto the_end; 1259b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case 0x02: /* write char */ 1260b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov { 1261b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov uint8_t c = r->edx; 1262b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov putchar(c); 1263b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1264b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 1265b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case 0x09: /* write string */ 1266b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov { 1267b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov uint8_t c, *ptr; 1268b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ptr = seg_to_linear(r->ds, r->edx); 1269b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for(;;) { 1270b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov c = *ptr++; 1271b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (c == '$') 1272b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 1273b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov putchar(c); 1274b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1275b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov r->eax = (r->eax & ~0xff) | '$'; 1276b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1277b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 1278b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case 0xff: /* extension: write eflags number in edx */ 1279b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov v = (int)r->edx; 1280b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#ifndef LINUX_VM86_IOPL_FIX 1281b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov v &= ~0x3000; 1282b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 1283b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("%08x\n", v); 1284b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 1285b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov default: 1286b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov unknown_int: 1287b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("unsupported int 0x%02x\n", int_num); 1288b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov goto the_end; 1289b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1290b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1291b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 1292b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case VM86_SIGNAL: 1293b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* a signal came, we just ignore that */ 1294b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 1295b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov case VM86_STI: 1296b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov break; 1297b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov default: 1298b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("ERROR: unhandled vm86 return code (0x%x)\n", ret); 1299b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov goto the_end; 1300b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1301b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1302b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov the_end: 1303b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("VM86 end\n"); 1304b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov munmap(vm86_mem, 0x110000); 1305b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 1306b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 1307b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1308b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* exception tests */ 1309b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if 0 1310b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#ifndef REG_EAX 1311b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define REG_EAX EAX 1312b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define REG_EBX EBX 1313b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define REG_ECX ECX 1314b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define REG_EDX EDX 1315b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define REG_ESI ESI 1316b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define REG_EDI EDI 1317b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define REG_EBP EBP 1318b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define REG_ESP ESP 1319b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define REG_EIP EIP 1320b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define REG_EFL EFL 1321b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define REG_TRAPNO TRAPNO 1322b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define REG_ERR ERR 1323b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 1324b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1325b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovjmp_buf jmp_env; 1326b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovint v1; 1327b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovint tab[2]; 1328b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1329b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid sig_handler(int sig, siginfo_t *info, void *puc) 1330b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 1331b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov struct ucontext *uc = puc; 1332b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1333b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("si_signo=%d si_errno=%d si_code=%d", 1334b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov info->si_signo, info->si_errno, info->si_code); 1335b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf(" si_addr=0x%08lx", 1336b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov (unsigned long)info->si_addr); 1337b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("\n"); 1338b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1339b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("trapno=0x%02x err=0x%08x", 1340b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov uc->uc_mcontext.gregs[REG_TRAPNO], 1341b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov uc->uc_mcontext.gregs[REG_ERR]); 1342b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf(" EIP=0x%08x", uc->uc_mcontext.gregs[REG_EIP]); 1343b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("\n"); 1344b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov longjmp(jmp_env, 1); 1345b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 1346b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1347b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid test_exceptions(void) 1348b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 1349b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov struct modify_ldt_ldt_s ldt; 1350b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov struct sigaction act; 1351b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile int val; 1352b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1353b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov act.sa_sigaction = sig_handler; 1354b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sigemptyset(&act.sa_mask); 1355b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov act.sa_flags = SA_SIGINFO; 1356b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sigaction(SIGFPE, &act, NULL); 1357b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sigaction(SIGILL, &act, NULL); 1358b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sigaction(SIGSEGV, &act, NULL); 1359b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sigaction(SIGBUS, &act, NULL); 1360b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sigaction(SIGTRAP, &act, NULL); 1361b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1362b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* test division by zero reporting */ 1363b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("DIVZ exception:\n"); 1364b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (setjmp(jmp_env) == 0) { 1365b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* now divide by zero */ 1366b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov v1 = 0; 1367b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov v1 = 2 / v1; 1368b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1369b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1370b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("BOUND exception:\n"); 1371b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (setjmp(jmp_env) == 0) { 1372b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* bound exception */ 1373b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov tab[0] = 1; 1374b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov tab[1] = 10; 1375b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("bound %0, %1" : : "r" (11), "m" (tab)); 1376b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1377b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1378b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("segment exceptions:\n"); 1379b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (setjmp(jmp_env) == 0) { 1380b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* load an invalid segment */ 1381b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("movl %0, %%fs" : : "r" ((0x1234 << 3) | 1)); 1382b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1383b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (setjmp(jmp_env) == 0) { 1384b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* null data segment is valid */ 1385b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("movl %0, %%fs" : : "r" (3)); 1386b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* null stack segment */ 1387b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("movl %0, %%ss" : : "r" (3)); 1388b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1389b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1390b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldt.entry_number = 1; 1391b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldt.base_addr = (unsigned long)&seg_data1; 1392b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldt.limit = (sizeof(seg_data1) + 0xfff) >> 12; 1393b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldt.seg_32bit = 1; 1394b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldt.contents = MODIFY_LDT_CONTENTS_DATA; 1395b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldt.read_exec_only = 0; 1396b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldt.limit_in_pages = 1; 1397b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldt.seg_not_present = 1; 1398b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ldt.useable = 1; 1399b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */ 1400b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1401b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (setjmp(jmp_env) == 0) { 1402b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* segment not present */ 1403b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("movl %0, %%fs" : : "r" (MK_SEL(1))); 1404b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1405b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1406b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* test SEGV reporting */ 1407b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("PF exception:\n"); 1408b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (setjmp(jmp_env) == 0) { 1409b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov val = 1; 1410b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* we add a nop to test a weird PC retrieval case */ 1411b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("nop"); 1412b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* now store in an invalid address */ 1413b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *(char *)0x1234 = 1; 1414b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1415b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1416b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* test SEGV reporting */ 1417b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("PF exception:\n"); 1418b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (setjmp(jmp_env) == 0) { 1419b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov val = 1; 1420b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* read from an invalid address */ 1421b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov v1 = *(char *)0x1234; 1422b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1423b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1424b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* test illegal instruction reporting */ 1425b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("UD2 exception:\n"); 1426b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (setjmp(jmp_env) == 0) { 1427b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* now execute an invalid instruction */ 1428b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile("ud2"); 1429b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1430b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("lock nop exception:\n"); 1431b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (setjmp(jmp_env) == 0) { 1432b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* now execute an invalid instruction */ 1433b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile("lock nop"); 1434b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1435b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1436b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("INT exception:\n"); 1437b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (setjmp(jmp_env) == 0) { 1438b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("int $0xfd"); 1439b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1440b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (setjmp(jmp_env) == 0) { 1441b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("int $0x01"); 1442b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1443b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (setjmp(jmp_env) == 0) { 1444b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile (".byte 0xcd, 0x03"); 1445b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1446b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (setjmp(jmp_env) == 0) { 1447b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("int $0x04"); 1448b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1449b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (setjmp(jmp_env) == 0) { 1450b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("int $0x05"); 1451b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1452b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1453b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("INT3 exception:\n"); 1454b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (setjmp(jmp_env) == 0) { 1455b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("int3"); 1456b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1457b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1458b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("CLI exception:\n"); 1459b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (setjmp(jmp_env) == 0) { 1460b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("cli"); 1461b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1462b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1463b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("STI exception:\n"); 1464b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (setjmp(jmp_env) == 0) { 1465b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("cli"); 1466b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1467b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1468b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("INTO exception:\n"); 1469b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (setjmp(jmp_env) == 0) { 1470b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* overflow exception */ 1471b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("addl $1, %0 ; into" : : "r" (0x7fffffff)); 1472b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1473b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1474b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("OUTB exception:\n"); 1475b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (setjmp(jmp_env) == 0) { 1476b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("outb %%al, %%dx" : : "d" (0x4321), "a" (0)); 1477b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1478b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1479b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("INB exception:\n"); 1480b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (setjmp(jmp_env) == 0) { 1481b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("inb %%dx, %%al" : "=a" (val) : "d" (0x4321)); 1482b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1483b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1484b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("REP OUTSB exception:\n"); 1485b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (setjmp(jmp_env) == 0) { 1486b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("rep outsb" : : "d" (0x4321), "S" (tab), "c" (1)); 1487b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1488b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1489b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("REP INSB exception:\n"); 1490b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (setjmp(jmp_env) == 0) { 1491b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("rep insb" : : "d" (0x4321), "D" (tab), "c" (1)); 1492b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1493b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1494b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("HLT exception:\n"); 1495b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (setjmp(jmp_env) == 0) { 1496b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("hlt"); 1497b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1498b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1499b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("single step exception:\n"); 1500b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov val = 0; 1501b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (setjmp(jmp_env) == 0) { 1502b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("pushf\n" 1503b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "orl $0x00100, (%%esp)\n" 1504b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "popf\n" 1505b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "movl $0xabcd, %0\n" 1506b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "movl $0x0, %0\n" : "=m" (val) : : "cc", "memory"); 1507b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1508b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("val=0x%x\n", val); 1509b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 1510b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1511b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* specific precise single step test */ 1512b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid sig_trap_handler(int sig, siginfo_t *info, void *puc) 1513b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 1514b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov struct ucontext *uc = puc; 1515b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("EIP=0x%08x\n", uc->uc_mcontext.gregs[REG_EIP]); 1516b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 1517b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1518b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovconst uint8_t sstep_buf1[4] = { 1, 2, 3, 4}; 1519b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovuint8_t sstep_buf2[4]; 1520b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1521b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid test_single_step(void) 1522b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 1523b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov struct sigaction act; 1524b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov volatile int val; 1525b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int i; 1526b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1527b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov val = 0; 1528b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov act.sa_sigaction = sig_trap_handler; 1529b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sigemptyset(&act.sa_mask); 1530b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov act.sa_flags = SA_SIGINFO; 1531b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov sigaction(SIGTRAP, &act, NULL); 1532b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov asm volatile ("pushf\n" 1533b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "orl $0x00100, (%%esp)\n" 1534b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "popf\n" 1535b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "movl $0xabcd, %0\n" 1536b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1537b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* jmp test */ 1538b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "movl $3, %%ecx\n" 1539b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "1:\n" 1540b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "addl $1, %0\n" 1541b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "decl %%ecx\n" 1542b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "jnz 1b\n" 1543b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1544b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* movsb: the single step should stop at each movsb iteration */ 1545b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "movl $sstep_buf1, %%esi\n" 1546b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "movl $sstep_buf2, %%edi\n" 1547b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "movl $0, %%ecx\n" 1548b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "rep movsb\n" 1549b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "movl $3, %%ecx\n" 1550b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "rep movsb\n" 1551b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "movl $1, %%ecx\n" 1552b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "rep movsb\n" 1553b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1554b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* cmpsb: the single step should stop at each cmpsb iteration */ 1555b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "movl $sstep_buf1, %%esi\n" 1556b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "movl $sstep_buf2, %%edi\n" 1557b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "movl $0, %%ecx\n" 1558b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "rep cmpsb\n" 1559b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "movl $4, %%ecx\n" 1560b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "rep cmpsb\n" 1561b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1562b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* getpid() syscall: single step should skip one 1563b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov instruction */ 1564b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "movl $20, %%eax\n" 1565b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "int $0x80\n" 1566b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "movl $0, %%eax\n" 1567b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1568b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* when modifying SS, trace is not done on the next 1569b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov instruction */ 1570b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "movl %%ss, %%ecx\n" 1571b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "movl %%ecx, %%ss\n" 1572b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "addl $1, %0\n" 1573b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "movl $1, %%eax\n" 1574b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "movl %%ecx, %%ss\n" 1575b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "jmp 1f\n" 1576b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "addl $1, %0\n" 1577b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "1:\n" 1578b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "movl $1, %%eax\n" 1579b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "pushl %%ecx\n" 1580b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "popl %%ss\n" 1581b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "addl $1, %0\n" 1582b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "movl $1, %%eax\n" 1583b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1584b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "pushf\n" 1585b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "andl $~0x00100, (%%esp)\n" 1586b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "popf\n" 1587b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "=m" (val) 1588b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : 1589b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov : "cc", "memory", "eax", "ecx", "esi", "edi"); 1590b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("val=%d\n", val); 1591b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for(i = 0; i < 4; i++) 1592b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("sstep_buf2[%d] = %d\n", i, sstep_buf2[i]); 1593b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 1594b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1595b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* self modifying code test */ 1596b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovuint8_t code[] = { 1597b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 0xb8, 0x1, 0x00, 0x00, 0x00, /* movl $1, %eax */ 1598b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 0xc3, /* ret */ 1599b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}; 1600b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1601b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovasm("smc_code2:\n" 1602b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "movl 4(%esp), %eax\n" 1603b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "movl %eax, smc_patch_addr2 + 1\n" 1604b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "nop\n" 1605b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "nop\n" 1606b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "nop\n" 1607b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "nop\n" 1608b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "nop\n" 1609b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "nop\n" 1610b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "nop\n" 1611b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "nop\n" 1612b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "smc_patch_addr2:\n" 1613b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "movl $1, %eax\n" 1614b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov "ret\n"); 1615b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1616b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovtypedef int FuncType(void); 1617b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovextern int smc_code2(int); 1618b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovvoid test_self_modifying_code(void) 1619b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 1620b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov int i; 1621b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1622b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("self modifying code:\n"); 1623b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("func1 = 0x%x\n", ((FuncType *)code)()); 1624b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for(i = 2; i <= 4; i++) { 1625b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov code[1] = i; 1626b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("func%d = 0x%x\n", i, ((FuncType *)code)()); 1627b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1628b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1629b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov /* more difficult test : the modified code is just after the 1630b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov modifying instruction. It is forbidden in Intel specs, but it 1631b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov is used by old DOS programs */ 1632b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov for(i = 2; i <= 4; i++) { 1633b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov printf("smc_code2(%d) = %d\n", i, smc_code2(i)); 1634b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1635b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 1636b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1637b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic void *call_end __init_call = NULL; 1638b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 1639b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1640b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovint main(int argc, char **argv) 1641b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{ 1642b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void **ptr; 1643b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov void (*func)(void); 1644b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 1645b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if 1 1646b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ptr = &call_start + 1; 1647b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov while (*ptr != NULL) { 1648b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov func = *ptr++; 1649b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov func(); 1650b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov } 1651b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#endif 1652b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_bsx(); 1653b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_mul(); 1654b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_jcc(); 1655b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_floats(); 1656b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov //test_bcd(); 1657b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_xchg(); 1658b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_string(); 1659b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_misc(); // REINSTATE 1660b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov test_lea(); 1661b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov // test_segs(); 1662b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov //test_code16(); 1663b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov //test_vm86(); 1664b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov //test_exceptions(); 1665b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov //test_self_modifying_code(); 1666b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov //test_single_step(); 1667b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov return 0; 1668b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov} 1669