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