~ubuntu-branches/ubuntu/vivid/golang/vivid

« back to all changes in this revision

Viewing changes to src/liblink/asm8.c

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn
  • Date: 2014-11-18 15:12:26 UTC
  • mfrom: (14.2.12 vivid-proposed)
  • Revision ID: package-import@ubuntu.com-20141118151226-zug7vn93mn3dtiz3
Tags: 2:1.3.2-1ubuntu1
* Merge from Debian unstable.  Remaining changes:
  - 016-armhf-elf-header.patch: Use correct ELF header for armhf binaries.
  - Support co-installability with gccgo-go tool:
    - d/rules,golang-go.install: Rename bin/go -> bin/golang-go
    - d/golang-go.{postinst,prerm}: Install/remove /usr/bin/go using
      alternatives.
  - d/copyright: Amendments for full compiliance with copyright format.
  - d/control: Demote golang-go.tools to Suggests to support Ubuntu MIR.
  - dropped patches (now upstream):
    - d/p/issue27650045_40001_50001.diff
    - d/p/issue28050043_60001_70001.diff
    - d/p/issue54790044_100001_110001.diff

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Inferno utils/8l/span.c
 
2
// http://code.google.com/p/inferno-os/source/browse/utils/8l/span.c
 
3
//
 
4
//      Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
 
5
//      Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
 
6
//      Portions Copyright © 1997-1999 Vita Nuova Limited
 
7
//      Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
 
8
//      Portions Copyright © 2004,2006 Bruce Ellis
 
9
//      Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
 
10
//      Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
 
11
//      Portions Copyright © 2009 The Go Authors.  All rights reserved.
 
12
//
 
13
// Permission is hereby granted, free of charge, to any person obtaining a copy
 
14
// of this software and associated documentation files (the "Software"), to deal
 
15
// in the Software without restriction, including without limitation the rights
 
16
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
17
// copies of the Software, and to permit persons to whom the Software is
 
18
// furnished to do so, subject to the following conditions:
 
19
//
 
20
// The above copyright notice and this permission notice shall be included in
 
21
// all copies or substantial portions of the Software.
 
22
//
 
23
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
24
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
25
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 
26
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
27
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
28
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
29
// THE SOFTWARE.
 
30
 
 
31
// Instruction layout.
 
32
 
 
33
#include <u.h>
 
34
#include <libc.h>
 
35
#include <bio.h>
 
36
#include <link.h>
 
37
#include "../cmd/8l/8.out.h"
 
38
#include "../pkg/runtime/stack.h"
 
39
 
 
40
enum
 
41
{
 
42
        MaxAlign = 32,  // max data alignment
 
43
        FuncAlign = 16
 
44
};
 
45
 
 
46
extern char *anames6[];
 
47
 
 
48
typedef struct  Optab   Optab;
 
49
 
 
50
struct  Optab
 
51
{
 
52
        short   as;
 
53
        uchar*  ytab;
 
54
        uchar   prefix;
 
55
        uchar   op[13];
 
56
};
 
57
 
 
58
enum
 
59
{
 
60
        Yxxx            = 0,
 
61
        Ynone,
 
62
        Yi0,
 
63
        Yi1,
 
64
        Yi8,
 
65
        Yi32,
 
66
        Yiauto,
 
67
        Yal,
 
68
        Ycl,
 
69
        Yax,
 
70
        Ycx,
 
71
        Yrb,
 
72
        Yrl,
 
73
        Yrf,
 
74
        Yf0,
 
75
        Yrx,
 
76
        Ymb,
 
77
        Yml,
 
78
        Ym,
 
79
        Ybr,
 
80
        Ycol,
 
81
        Ytls,
 
82
 
 
83
        Ycs,    Yss,    Yds,    Yes,    Yfs,    Ygs,
 
84
        Ygdtr,  Yidtr,  Yldtr,  Ymsw,   Ytask,
 
85
        Ycr0,   Ycr1,   Ycr2,   Ycr3,   Ycr4,   Ycr5,   Ycr6,   Ycr7,
 
86
        Ydr0,   Ydr1,   Ydr2,   Ydr3,   Ydr4,   Ydr5,   Ydr6,   Ydr7,
 
87
        Ytr0,   Ytr1,   Ytr2,   Ytr3,   Ytr4,   Ytr5,   Ytr6,   Ytr7,
 
88
        Ymr, Ymm,
 
89
        Yxr, Yxm,
 
90
        Ymax,
 
91
 
 
92
        Zxxx            = 0,
 
93
 
 
94
        Zlit,
 
95
        Zlitm_r,
 
96
        Z_rp,
 
97
        Zbr,
 
98
        Zcall,
 
99
        Zcallcon,
 
100
        Zcallind,
 
101
        Zcallindreg,
 
102
        Zib_,
 
103
        Zib_rp,
 
104
        Zibo_m,
 
105
        Zil_,
 
106
        Zil_rp,
 
107
        Zilo_m,
 
108
        Zjmp,
 
109
        Zjmpcon,
 
110
        Zloop,
 
111
        Zm_o,
 
112
        Zm_r,
 
113
        Zm2_r,
 
114
        Zm_r_xm,
 
115
        Zm_r_i_xm,
 
116
        Zaut_r,
 
117
        Zo_m,
 
118
        Zpseudo,
 
119
        Zr_m,
 
120
        Zr_m_xm,
 
121
        Zr_m_i_xm,
 
122
        Zrp_,
 
123
        Z_ib,
 
124
        Z_il,
 
125
        Zm_ibo,
 
126
        Zm_ilo,
 
127
        Zib_rr,
 
128
        Zil_rr,
 
129
        Zclr,
 
130
        Zibm_r, /* mmx1,mmx2/mem64,imm8 */
 
131
        Zbyte,
 
132
        Zmov,
 
133
        Zmax,
 
134
 
 
135
        Px              = 0,
 
136
        Pe              = 0x66, /* operand escape */
 
137
        Pm              = 0x0f, /* 2byte opcode escape */
 
138
        Pq              = 0xff, /* both escape */
 
139
        Pb              = 0xfe, /* byte operands */
 
140
        Pf2             = 0xf2, /* xmm escape 1 */
 
141
        Pf3             = 0xf3, /* xmm escape 2 */
 
142
};
 
143
 
 
144
static  uchar   ycover[Ymax*Ymax];
 
145
static  char    reg[D_NONE];
 
146
static  void    asmins(Link *ctxt, Prog *p);
 
147
 
 
148
static uchar    ynone[] =
 
149
{
 
150
        Ynone,  Ynone,  Zlit,   1,
 
151
        0
 
152
};
 
153
static uchar    ytext[] =
 
154
{
 
155
        Ymb,    Yi32,   Zpseudo,1,
 
156
        0
 
157
};
 
158
static uchar    ynop[] =
 
159
{
 
160
        Ynone,  Ynone,  Zpseudo,0,
 
161
        Ynone,  Yiauto, Zpseudo,0,
 
162
        Ynone,  Yml,    Zpseudo,0,
 
163
        Ynone,  Yrf,    Zpseudo,0,
 
164
        Yiauto, Ynone,  Zpseudo,0,
 
165
        Ynone,  Yxr,    Zpseudo,0,
 
166
        Yml,    Ynone,  Zpseudo,0,
 
167
        Yrf,    Ynone,  Zpseudo,0,
 
168
        Yxr,    Ynone,  Zpseudo,1,
 
169
        0
 
170
};
 
171
static uchar    yfuncdata[] =
 
172
{
 
173
        Yi32,   Ym,     Zpseudo,        0,
 
174
        0
 
175
};
 
176
static uchar    ypcdata[] =
 
177
{
 
178
        Yi32,   Yi32,   Zpseudo,        0,
 
179
        0,
 
180
};
 
181
static uchar    yxorb[] =
 
182
{
 
183
        Yi32,   Yal,    Zib_,   1,
 
184
        Yi32,   Ymb,    Zibo_m, 2,
 
185
        Yrb,    Ymb,    Zr_m,   1,
 
186
        Ymb,    Yrb,    Zm_r,   1,
 
187
        0
 
188
};
 
189
static uchar    yxorl[] =
 
190
{
 
191
        Yi8,    Yml,    Zibo_m, 2,
 
192
        Yi32,   Yax,    Zil_,   1,
 
193
        Yi32,   Yml,    Zilo_m, 2,
 
194
        Yrl,    Yml,    Zr_m,   1,
 
195
        Yml,    Yrl,    Zm_r,   1,
 
196
        0
 
197
};
 
198
static uchar    yaddl[] =
 
199
{
 
200
        Yi8,    Yml,    Zibo_m, 2,
 
201
        Yi32,   Yax,    Zil_,   1,
 
202
        Yi32,   Yml,    Zilo_m, 2,
 
203
        Yrl,    Yml,    Zr_m,   1,
 
204
        Yml,    Yrl,    Zm_r,   1,
 
205
        0
 
206
};
 
207
static uchar    yincb[] =
 
208
{
 
209
        Ynone,  Ymb,    Zo_m,   2,
 
210
        0
 
211
};
 
212
static uchar    yincl[] =
 
213
{
 
214
        Ynone,  Yrl,    Z_rp,   1,
 
215
        Ynone,  Yml,    Zo_m,   2,
 
216
        0
 
217
};
 
218
static uchar    ycmpb[] =
 
219
{
 
220
        Yal,    Yi32,   Z_ib,   1,
 
221
        Ymb,    Yi32,   Zm_ibo, 2,
 
222
        Ymb,    Yrb,    Zm_r,   1,
 
223
        Yrb,    Ymb,    Zr_m,   1,
 
224
        0
 
225
};
 
226
static uchar    ycmpl[] =
 
227
{
 
228
        Yml,    Yi8,    Zm_ibo, 2,
 
229
        Yax,    Yi32,   Z_il,   1,
 
230
        Yml,    Yi32,   Zm_ilo, 2,
 
231
        Yml,    Yrl,    Zm_r,   1,
 
232
        Yrl,    Yml,    Zr_m,   1,
 
233
        0
 
234
};
 
235
static uchar    yshb[] =
 
236
{
 
237
        Yi1,    Ymb,    Zo_m,   2,
 
238
        Yi32,   Ymb,    Zibo_m, 2,
 
239
        Ycx,    Ymb,    Zo_m,   2,
 
240
        0
 
241
};
 
242
static uchar    yshl[] =
 
243
{
 
244
        Yi1,    Yml,    Zo_m,   2,
 
245
        Yi32,   Yml,    Zibo_m, 2,
 
246
        Ycl,    Yml,    Zo_m,   2,
 
247
        Ycx,    Yml,    Zo_m,   2,
 
248
        0
 
249
};
 
250
static uchar    ytestb[] =
 
251
{
 
252
        Yi32,   Yal,    Zib_,   1,
 
253
        Yi32,   Ymb,    Zibo_m, 2,
 
254
        Yrb,    Ymb,    Zr_m,   1,
 
255
        Ymb,    Yrb,    Zm_r,   1,
 
256
        0
 
257
};
 
258
static uchar    ytestl[] =
 
259
{
 
260
        Yi32,   Yax,    Zil_,   1,
 
261
        Yi32,   Yml,    Zilo_m, 2,
 
262
        Yrl,    Yml,    Zr_m,   1,
 
263
        Yml,    Yrl,    Zm_r,   1,
 
264
        0
 
265
};
 
266
static uchar    ymovb[] =
 
267
{
 
268
        Yrb,    Ymb,    Zr_m,   1,
 
269
        Ymb,    Yrb,    Zm_r,   1,
 
270
        Yi32,   Yrb,    Zib_rp, 1,
 
271
        Yi32,   Ymb,    Zibo_m, 2,
 
272
        0
 
273
};
 
274
static uchar    ymovw[] =
 
275
{
 
276
        Yrl,    Yml,    Zr_m,   1,
 
277
        Yml,    Yrl,    Zm_r,   1,
 
278
        Yi0,    Yrl,    Zclr,   1+2,
 
279
//      Yi0,    Yml,    Zibo_m, 2,      // shorter but slower AND $0,dst
 
280
        Yi32,   Yrl,    Zil_rp, 1,
 
281
        Yi32,   Yml,    Zilo_m, 2,
 
282
        Yiauto, Yrl,    Zaut_r, 1,
 
283
        0
 
284
};
 
285
static uchar    ymovl[] =
 
286
{
 
287
        Yrl,    Yml,    Zr_m,   1,
 
288
        Yml,    Yrl,    Zm_r,   1,
 
289
        Yi0,    Yrl,    Zclr,   1+2,
 
290
//      Yi0,    Yml,    Zibo_m, 2,      // shorter but slower AND $0,dst
 
291
        Yi32,   Yrl,    Zil_rp, 1,
 
292
        Yi32,   Yml,    Zilo_m, 2,
 
293
        Yml,    Yxr,    Zm_r_xm,        2,      // XMM MOVD (32 bit)
 
294
        Yxr,    Yml,    Zr_m_xm,        2,      // XMM MOVD (32 bit)
 
295
        Yiauto, Yrl,    Zaut_r, 1,
 
296
        0
 
297
};
 
298
static uchar    ymovq[] =
 
299
{
 
300
        Yml,    Yxr,    Zm_r_xm,        2,
 
301
        0
 
302
};
 
303
static uchar    ym_rl[] =
 
304
{
 
305
        Ym,     Yrl,    Zm_r,   1,
 
306
        0
 
307
};
 
308
static uchar    yrl_m[] =
 
309
{
 
310
        Yrl,    Ym,     Zr_m,   1,
 
311
        0
 
312
};
 
313
static uchar    ymb_rl[] =
 
314
{
 
315
        Ymb,    Yrl,    Zm_r,   1,
 
316
        0
 
317
};
 
318
static uchar    yml_rl[] =
 
319
{
 
320
        Yml,    Yrl,    Zm_r,   1,
 
321
        0
 
322
};
 
323
static uchar    yrb_mb[] =
 
324
{
 
325
        Yrb,    Ymb,    Zr_m,   1,
 
326
        0
 
327
};
 
328
static uchar    yrl_ml[] =
 
329
{
 
330
        Yrl,    Yml,    Zr_m,   1,
 
331
        0
 
332
};
 
333
static uchar    yml_mb[] =
 
334
{
 
335
        Yrb,    Ymb,    Zr_m,   1,
 
336
        Ymb,    Yrb,    Zm_r,   1,
 
337
        0
 
338
};
 
339
static uchar    yxchg[] =
 
340
{
 
341
        Yax,    Yrl,    Z_rp,   1,
 
342
        Yrl,    Yax,    Zrp_,   1,
 
343
        Yrl,    Yml,    Zr_m,   1,
 
344
        Yml,    Yrl,    Zm_r,   1,
 
345
        0
 
346
};
 
347
static uchar    ydivl[] =
 
348
{
 
349
        Yml,    Ynone,  Zm_o,   2,
 
350
        0
 
351
};
 
352
static uchar    ydivb[] =
 
353
{
 
354
        Ymb,    Ynone,  Zm_o,   2,
 
355
        0
 
356
};
 
357
static uchar    yimul[] =
 
358
{
 
359
        Yml,    Ynone,  Zm_o,   2,
 
360
        Yi8,    Yrl,    Zib_rr, 1,
 
361
        Yi32,   Yrl,    Zil_rr, 1,
 
362
        0
 
363
};
 
364
static uchar    ybyte[] =
 
365
{
 
366
        Yi32,   Ynone,  Zbyte,  1,
 
367
        0
 
368
};
 
369
static uchar    yin[] =
 
370
{
 
371
        Yi32,   Ynone,  Zib_,   1,
 
372
        Ynone,  Ynone,  Zlit,   1,
 
373
        0
 
374
};
 
375
static uchar    yint[] =
 
376
{
 
377
        Yi32,   Ynone,  Zib_,   1,
 
378
        0
 
379
};
 
380
static uchar    ypushl[] =
 
381
{
 
382
        Yrl,    Ynone,  Zrp_,   1,
 
383
        Ym,     Ynone,  Zm_o,   2,
 
384
        Yi8,    Ynone,  Zib_,   1,
 
385
        Yi32,   Ynone,  Zil_,   1,
 
386
        0
 
387
};
 
388
static uchar    ypopl[] =
 
389
{
 
390
        Ynone,  Yrl,    Z_rp,   1,
 
391
        Ynone,  Ym,     Zo_m,   2,
 
392
        0
 
393
};
 
394
static uchar    ybswap[] =
 
395
{
 
396
        Ynone,  Yrl,    Z_rp,   1,
 
397
        0,
 
398
};
 
399
static uchar    yscond[] =
 
400
{
 
401
        Ynone,  Ymb,    Zo_m,   2,
 
402
        0
 
403
};
 
404
static uchar    yjcond[] =
 
405
{
 
406
        Ynone,  Ybr,    Zbr,    0,
 
407
        Yi0,    Ybr,    Zbr,    0,
 
408
        Yi1,    Ybr,    Zbr,    1,
 
409
        0
 
410
};
 
411
static uchar    yloop[] =
 
412
{
 
413
        Ynone,  Ybr,    Zloop,  1,
 
414
        0
 
415
};
 
416
static uchar    ycall[] =
 
417
{
 
418
        Ynone,  Yml,    Zcallindreg,    0,
 
419
        Yrx,    Yrx,    Zcallindreg,    2,
 
420
        Ynone,  Ycol,   Zcallind,       2,
 
421
        Ynone,  Ybr,    Zcall,  0,
 
422
        Ynone,  Yi32,   Zcallcon,       1,
 
423
        0
 
424
};
 
425
static uchar    yduff[] =
 
426
{
 
427
        Ynone,  Yi32,   Zcall,  1,
 
428
        0
 
429
};
 
430
static uchar    yjmp[] =
 
431
{
 
432
        Ynone,  Yml,    Zo_m,   2,
 
433
        Ynone,  Ybr,    Zjmp,   0,
 
434
        Ynone,  Yi32,   Zjmpcon,        1,
 
435
        0
 
436
};
 
437
 
 
438
static uchar    yfmvd[] =
 
439
{
 
440
        Ym,     Yf0,    Zm_o,   2,
 
441
        Yf0,    Ym,     Zo_m,   2,
 
442
        Yrf,    Yf0,    Zm_o,   2,
 
443
        Yf0,    Yrf,    Zo_m,   2,
 
444
        0
 
445
};
 
446
static uchar    yfmvdp[] =
 
447
{
 
448
        Yf0,    Ym,     Zo_m,   2,
 
449
        Yf0,    Yrf,    Zo_m,   2,
 
450
        0
 
451
};
 
452
static uchar    yfmvf[] =
 
453
{
 
454
        Ym,     Yf0,    Zm_o,   2,
 
455
        Yf0,    Ym,     Zo_m,   2,
 
456
        0
 
457
};
 
458
static uchar    yfmvx[] =
 
459
{
 
460
        Ym,     Yf0,    Zm_o,   2,
 
461
        0
 
462
};
 
463
static uchar    yfmvp[] =
 
464
{
 
465
        Yf0,    Ym,     Zo_m,   2,
 
466
        0
 
467
};
 
468
static uchar    yfcmv[] =
 
469
{
 
470
        Yrf,    Yf0,    Zm_o,   2,
 
471
        0
 
472
};
 
473
static uchar    yfadd[] =
 
474
{
 
475
        Ym,     Yf0,    Zm_o,   2,
 
476
        Yrf,    Yf0,    Zm_o,   2,
 
477
        Yf0,    Yrf,    Zo_m,   2,
 
478
        0
 
479
};
 
480
static uchar    yfaddp[] =
 
481
{
 
482
        Yf0,    Yrf,    Zo_m,   2,
 
483
        0
 
484
};
 
485
static uchar    yfxch[] =
 
486
{
 
487
        Yf0,    Yrf,    Zo_m,   2,
 
488
        Yrf,    Yf0,    Zm_o,   2,
 
489
        0
 
490
};
 
491
static uchar    ycompp[] =
 
492
{
 
493
        Yf0,    Yrf,    Zo_m,   2,      /* botch is really f0,f1 */
 
494
        0
 
495
};
 
496
static uchar    ystsw[] =
 
497
{
 
498
        Ynone,  Ym,     Zo_m,   2,
 
499
        Ynone,  Yax,    Zlit,   1,
 
500
        0
 
501
};
 
502
static uchar    ystcw[] =
 
503
{
 
504
        Ynone,  Ym,     Zo_m,   2,
 
505
        Ym,     Ynone,  Zm_o,   2,
 
506
        0
 
507
};
 
508
static uchar    ysvrs[] =
 
509
{
 
510
        Ynone,  Ym,     Zo_m,   2,
 
511
        Ym,     Ynone,  Zm_o,   2,
 
512
        0
 
513
};
 
514
static uchar    ymskb[] =
 
515
{
 
516
        Yxr,    Yrl,    Zm_r_xm,        2,
 
517
        Ymr,    Yrl,    Zm_r_xm,        1,
 
518
        0
 
519
};
 
520
static uchar    yxm[] = 
 
521
{
 
522
        Yxm,    Yxr,    Zm_r_xm,        1,
 
523
        0
 
524
};
 
525
static uchar    yxcvm1[] = 
 
526
{
 
527
        Yxm,    Yxr,    Zm_r_xm,        2,
 
528
        Yxm,    Ymr,    Zm_r_xm,        2,
 
529
        0
 
530
};
 
531
static uchar    yxcvm2[] =
 
532
{
 
533
        Yxm,    Yxr,    Zm_r_xm,        2,
 
534
        Ymm,    Yxr,    Zm_r_xm,        2,
 
535
        0
 
536
};
 
537
static uchar    yxmq[] = 
 
538
{
 
539
        Yxm,    Yxr,    Zm_r_xm,        2,
 
540
        0
 
541
};
 
542
static uchar    yxr[] = 
 
543
{
 
544
        Yxr,    Yxr,    Zm_r_xm,        1,
 
545
        0
 
546
};
 
547
static uchar    yxr_ml[] =
 
548
{
 
549
        Yxr,    Yml,    Zr_m_xm,        1,
 
550
        0
 
551
};
 
552
static uchar    yxcmp[] =
 
553
{
 
554
        Yxm,    Yxr, Zm_r_xm,   1,
 
555
        0
 
556
};
 
557
static uchar    yxcmpi[] =
 
558
{
 
559
        Yxm,    Yxr, Zm_r_i_xm, 2,
 
560
        0
 
561
};
 
562
static uchar    yxmov[] =
 
563
{
 
564
        Yxm,    Yxr,    Zm_r_xm,        1,
 
565
        Yxr,    Yxm,    Zr_m_xm,        1,
 
566
        0
 
567
};
 
568
static uchar    yxcvfl[] = 
 
569
{
 
570
        Yxm,    Yrl,    Zm_r_xm,        1,
 
571
        0
 
572
};
 
573
static uchar    yxcvlf[] =
 
574
{
 
575
        Yml,    Yxr,    Zm_r_xm,        1,
 
576
        0
 
577
};
 
578
/*
 
579
static uchar    yxcvfq[] = 
 
580
{
 
581
        Yxm,    Yrl,    Zm_r_xm,        2,
 
582
        0
 
583
};
 
584
static uchar    yxcvqf[] =
 
585
{
 
586
        Yml,    Yxr,    Zm_r_xm,        2,
 
587
        0
 
588
};
 
589
*/
 
590
static uchar    yxrrl[] =
 
591
{
 
592
        Yxr,    Yrl,    Zm_r,   1,
 
593
        0
 
594
};
 
595
static uchar    yprefetch[] =
 
596
{
 
597
        Ym,     Ynone,  Zm_o,   2,
 
598
        0,
 
599
};
 
600
static uchar    yaes[] =
 
601
{
 
602
        Yxm,    Yxr,    Zlitm_r,        2,
 
603
        0
 
604
};
 
605
static uchar    yinsrd[] =
 
606
{
 
607
        Yml,    Yxr,    Zibm_r, 2,
 
608
        0
 
609
};
 
610
static uchar    ymshufb[] =
 
611
{
 
612
        Yxm,    Yxr,    Zm2_r,  2,
 
613
        0
 
614
};
 
615
 
 
616
static Optab optab[] =
 
617
/*      as, ytab, andproto, opcode */
 
618
{
 
619
        { AXXX },
 
620
        { AAAA,         ynone,  Px, 0x37 },
 
621
        { AAAD,         ynone,  Px, 0xd5,0x0a },
 
622
        { AAAM,         ynone,  Px, 0xd4,0x0a },
 
623
        { AAAS,         ynone,  Px, 0x3f },
 
624
        { AADCB,        yxorb,  Pb, 0x14,0x80,(02),0x10,0x10 },
 
625
        { AADCL,        yxorl,  Px, 0x83,(02),0x15,0x81,(02),0x11,0x13 },
 
626
        { AADCW,        yxorl,  Pe, 0x83,(02),0x15,0x81,(02),0x11,0x13 },
 
627
        { AADDB,        yxorb,  Px, 0x04,0x80,(00),0x00,0x02 },
 
628
        { AADDL,        yaddl,  Px, 0x83,(00),0x05,0x81,(00),0x01,0x03 },
 
629
        { AADDW,        yaddl,  Pe, 0x83,(00),0x05,0x81,(00),0x01,0x03 },
 
630
        { AADJSP },
 
631
        { AANDB,        yxorb,  Pb, 0x24,0x80,(04),0x20,0x22 },
 
632
        { AANDL,        yxorl,  Px, 0x83,(04),0x25,0x81,(04),0x21,0x23 },
 
633
        { AANDW,        yxorl,  Pe, 0x83,(04),0x25,0x81,(04),0x21,0x23 },
 
634
        { AARPL,        yrl_ml, Px, 0x63 },
 
635
        { ABOUNDL,      yrl_m,  Px, 0x62 },
 
636
        { ABOUNDW,      yrl_m,  Pe, 0x62 },
 
637
        { ABSFL,        yml_rl, Pm, 0xbc },
 
638
        { ABSFW,        yml_rl, Pq, 0xbc },
 
639
        { ABSRL,        yml_rl, Pm, 0xbd },
 
640
        { ABSRW,        yml_rl, Pq, 0xbd },
 
641
        { ABTL,         yml_rl, Pm, 0xa3 },
 
642
        { ABTW,         yml_rl, Pq, 0xa3 },
 
643
        { ABTCL,        yml_rl, Pm, 0xbb },
 
644
        { ABTCW,        yml_rl, Pq, 0xbb },
 
645
        { ABTRL,        yml_rl, Pm, 0xb3 },
 
646
        { ABTRW,        yml_rl, Pq, 0xb3 },
 
647
        { ABTSL,        yml_rl, Pm, 0xab },
 
648
        { ABTSW,        yml_rl, Pq, 0xab },
 
649
        { ABYTE,        ybyte,  Px, 1 },
 
650
        { ACALL,        ycall,  Px, 0xff,(02),0xff,(0x15),0xe8 },
 
651
        { ACLC,         ynone,  Px, 0xf8 },
 
652
        { ACLD,         ynone,  Px, 0xfc },
 
653
        { ACLI,         ynone,  Px, 0xfa },
 
654
        { ACLTS,        ynone,  Pm, 0x06 },
 
655
        { ACMC,         ynone,  Px, 0xf5 },
 
656
        { ACMPB,        ycmpb,  Pb, 0x3c,0x80,(07),0x38,0x3a },
 
657
        { ACMPL,        ycmpl,  Px, 0x83,(07),0x3d,0x81,(07),0x39,0x3b },
 
658
        { ACMPW,        ycmpl,  Pe, 0x83,(07),0x3d,0x81,(07),0x39,0x3b },
 
659
        { ACMPSB,       ynone,  Pb, 0xa6 },
 
660
        { ACMPSL,       ynone,  Px, 0xa7 },
 
661
        { ACMPSW,       ynone,  Pe, 0xa7 },
 
662
        { ADAA,         ynone,  Px, 0x27 },
 
663
        { ADAS,         ynone,  Px, 0x2f },
 
664
        { ADATA },
 
665
        { ADECB,        yincb,  Pb, 0xfe,(01) },
 
666
        { ADECL,        yincl,  Px, 0x48,0xff,(01) },
 
667
        { ADECW,        yincl,  Pe, 0x48,0xff,(01) },
 
668
        { ADIVB,        ydivb,  Pb, 0xf6,(06) },
 
669
        { ADIVL,        ydivl,  Px, 0xf7,(06) },
 
670
        { ADIVW,        ydivl,  Pe, 0xf7,(06) },
 
671
        { AENTER },                             /* botch */
 
672
        { AGLOBL },
 
673
        { AGOK },
 
674
        { AHISTORY },
 
675
        { AHLT,         ynone,  Px, 0xf4 },
 
676
        { AIDIVB,       ydivb,  Pb, 0xf6,(07) },
 
677
        { AIDIVL,       ydivl,  Px, 0xf7,(07) },
 
678
        { AIDIVW,       ydivl,  Pe, 0xf7,(07) },
 
679
        { AIMULB,       ydivb,  Pb, 0xf6,(05) },
 
680
        { AIMULL,       yimul,  Px, 0xf7,(05),0x6b,0x69 },
 
681
        { AIMULW,       yimul,  Pe, 0xf7,(05),0x6b,0x69 },
 
682
        { AINB,         yin,    Pb, 0xe4,0xec },
 
683
        { AINL,         yin,    Px, 0xe5,0xed },
 
684
        { AINW,         yin,    Pe, 0xe5,0xed },
 
685
        { AINCB,        yincb,  Pb, 0xfe,(00) },
 
686
        { AINCL,        yincl,  Px, 0x40,0xff,(00) },
 
687
        { AINCW,        yincl,  Pe, 0x40,0xff,(00) },
 
688
        { AINSB,        ynone,  Pb, 0x6c },
 
689
        { AINSL,        ynone,  Px, 0x6d },
 
690
        { AINSW,        ynone,  Pe, 0x6d },
 
691
        { AINT,         yint,   Px, 0xcd },
 
692
        { AINTO,        ynone,  Px, 0xce },
 
693
        { AIRETL,       ynone,  Px, 0xcf },
 
694
        { AIRETW,       ynone,  Pe, 0xcf },
 
695
        { AJCC,         yjcond, Px, 0x73,0x83,(00) },
 
696
        { AJCS,         yjcond, Px, 0x72,0x82 },
 
697
        { AJCXZL,       yloop,  Px, 0xe3 },
 
698
        { AJCXZW,       yloop,  Px, 0xe3 },
 
699
        { AJEQ,         yjcond, Px, 0x74,0x84 },
 
700
        { AJGE,         yjcond, Px, 0x7d,0x8d },
 
701
        { AJGT,         yjcond, Px, 0x7f,0x8f },
 
702
        { AJHI,         yjcond, Px, 0x77,0x87 },
 
703
        { AJLE,         yjcond, Px, 0x7e,0x8e },
 
704
        { AJLS,         yjcond, Px, 0x76,0x86 },
 
705
        { AJLT,         yjcond, Px, 0x7c,0x8c },
 
706
        { AJMI,         yjcond, Px, 0x78,0x88 },
 
707
        { AJMP,         yjmp,   Px, 0xff,(04),0xeb,0xe9 },
 
708
        { AJNE,         yjcond, Px, 0x75,0x85 },
 
709
        { AJOC,         yjcond, Px, 0x71,0x81,(00) },
 
710
        { AJOS,         yjcond, Px, 0x70,0x80,(00) },
 
711
        { AJPC,         yjcond, Px, 0x7b,0x8b },
 
712
        { AJPL,         yjcond, Px, 0x79,0x89 },
 
713
        { AJPS,         yjcond, Px, 0x7a,0x8a },
 
714
        { ALAHF,        ynone,  Px, 0x9f },
 
715
        { ALARL,        yml_rl, Pm, 0x02 },
 
716
        { ALARW,        yml_rl, Pq, 0x02 },
 
717
        { ALEAL,        ym_rl,  Px, 0x8d },
 
718
        { ALEAW,        ym_rl,  Pe, 0x8d },
 
719
        { ALEAVEL,      ynone,  Px, 0xc9 },
 
720
        { ALEAVEW,      ynone,  Pe, 0xc9 },
 
721
        { ALOCK,        ynone,  Px, 0xf0 },
 
722
        { ALODSB,       ynone,  Pb, 0xac },
 
723
        { ALODSL,       ynone,  Px, 0xad },
 
724
        { ALODSW,       ynone,  Pe, 0xad },
 
725
        { ALONG,        ybyte,  Px, 4 },
 
726
        { ALOOP,        yloop,  Px, 0xe2 },
 
727
        { ALOOPEQ,      yloop,  Px, 0xe1 },
 
728
        { ALOOPNE,      yloop,  Px, 0xe0 },
 
729
        { ALSLL,        yml_rl, Pm, 0x03  },
 
730
        { ALSLW,        yml_rl, Pq, 0x03  },
 
731
        { AMOVB,        ymovb,  Pb, 0x88,0x8a,0xb0,0xc6,(00) },
 
732
        { AMOVL,        ymovl,  Px, 0x89,0x8b,0x31,0x83,(04),0xb8,0xc7,(00),Pe,0x6e,Pe,0x7e,0 },
 
733
        { AMOVW,        ymovw,  Pe, 0x89,0x8b,0x31,0x83,(04),0xb8,0xc7,(00),0 },
 
734
        { AMOVQ,        ymovq,  Pf3, 0x7e },
 
735
        { AMOVBLSX,     ymb_rl, Pm, 0xbe },
 
736
        { AMOVBLZX,     ymb_rl, Pm, 0xb6 },
 
737
        { AMOVBWSX,     ymb_rl, Pq, 0xbe },
 
738
        { AMOVBWZX,     ymb_rl, Pq, 0xb6 },
 
739
        { AMOVWLSX,     yml_rl, Pm, 0xbf },
 
740
        { AMOVWLZX,     yml_rl, Pm, 0xb7 },
 
741
        { AMOVSB,       ynone,  Pb, 0xa4 },
 
742
        { AMOVSL,       ynone,  Px, 0xa5 },
 
743
        { AMOVSW,       ynone,  Pe, 0xa5 },
 
744
        { AMULB,        ydivb,  Pb, 0xf6,(04) },
 
745
        { AMULL,        ydivl,  Px, 0xf7,(04) },
 
746
        { AMULW,        ydivl,  Pe, 0xf7,(04) },
 
747
        { ANAME },
 
748
        { ANEGB,        yscond, Px, 0xf6,(03) },
 
749
        { ANEGL,        yscond, Px, 0xf7,(03) },
 
750
        { ANEGW,        yscond, Pe, 0xf7,(03) },
 
751
        { ANOP,         ynop,   Px,0,0 },
 
752
        { ANOTB,        yscond, Px, 0xf6,(02) },
 
753
        { ANOTL,        yscond, Px, 0xf7,(02) },
 
754
        { ANOTW,        yscond, Pe, 0xf7,(02) },
 
755
        { AORB,         yxorb,  Pb, 0x0c,0x80,(01),0x08,0x0a },
 
756
        { AORL,         yxorl,  Px, 0x83,(01),0x0d,0x81,(01),0x09,0x0b },
 
757
        { AORW,         yxorl,  Pe, 0x83,(01),0x0d,0x81,(01),0x09,0x0b },
 
758
        { AOUTB,        yin,    Pb, 0xe6,0xee },
 
759
        { AOUTL,        yin,    Px, 0xe7,0xef },
 
760
        { AOUTW,        yin,    Pe, 0xe7,0xef },
 
761
        { AOUTSB,       ynone,  Pb, 0x6e },
 
762
        { AOUTSL,       ynone,  Px, 0x6f },
 
763
        { AOUTSW,       ynone,  Pe, 0x6f },
 
764
        { APAUSE,       ynone,  Px, 0xf3,0x90 },
 
765
        { APOPAL,       ynone,  Px, 0x61 },
 
766
        { APOPAW,       ynone,  Pe, 0x61 },
 
767
        { APOPFL,       ynone,  Px, 0x9d },
 
768
        { APOPFW,       ynone,  Pe, 0x9d },
 
769
        { APOPL,        ypopl,  Px, 0x58,0x8f,(00) },
 
770
        { APOPW,        ypopl,  Pe, 0x58,0x8f,(00) },
 
771
        { APUSHAL,      ynone,  Px, 0x60 },
 
772
        { APUSHAW,      ynone,  Pe, 0x60 },
 
773
        { APUSHFL,      ynone,  Px, 0x9c },
 
774
        { APUSHFW,      ynone,  Pe, 0x9c },
 
775
        { APUSHL,       ypushl, Px, 0x50,0xff,(06),0x6a,0x68 },
 
776
        { APUSHW,       ypushl, Pe, 0x50,0xff,(06),0x6a,0x68 },
 
777
        { ARCLB,        yshb,   Pb, 0xd0,(02),0xc0,(02),0xd2,(02) },
 
778
        { ARCLL,        yshl,   Px, 0xd1,(02),0xc1,(02),0xd3,(02),0xd3,(02) },
 
779
        { ARCLW,        yshl,   Pe, 0xd1,(02),0xc1,(02),0xd3,(02),0xd3,(02) },
 
780
        { ARCRB,        yshb,   Pb, 0xd0,(03),0xc0,(03),0xd2,(03) },
 
781
        { ARCRL,        yshl,   Px, 0xd1,(03),0xc1,(03),0xd3,(03),0xd3,(03) },
 
782
        { ARCRW,        yshl,   Pe, 0xd1,(03),0xc1,(03),0xd3,(03),0xd3,(03) },
 
783
        { AREP,         ynone,  Px, 0xf3 },
 
784
        { AREPN,        ynone,  Px, 0xf2 },
 
785
        { ARET,         ynone,  Px, 0xc3 },
 
786
        { AROLB,        yshb,   Pb, 0xd0,(00),0xc0,(00),0xd2,(00) },
 
787
        { AROLL,        yshl,   Px, 0xd1,(00),0xc1,(00),0xd3,(00),0xd3,(00) },
 
788
        { AROLW,        yshl,   Pe, 0xd1,(00),0xc1,(00),0xd3,(00),0xd3,(00) },
 
789
        { ARORB,        yshb,   Pb, 0xd0,(01),0xc0,(01),0xd2,(01) },
 
790
        { ARORL,        yshl,   Px, 0xd1,(01),0xc1,(01),0xd3,(01),0xd3,(01) },
 
791
        { ARORW,        yshl,   Pe, 0xd1,(01),0xc1,(01),0xd3,(01),0xd3,(01) },
 
792
        { ASAHF,        ynone,  Px, 0x9e },
 
793
        { ASALB,        yshb,   Pb, 0xd0,(04),0xc0,(04),0xd2,(04) },
 
794
        { ASALL,        yshl,   Px, 0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04) },
 
795
        { ASALW,        yshl,   Pe, 0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04) },
 
796
        { ASARB,        yshb,   Pb, 0xd0,(07),0xc0,(07),0xd2,(07) },
 
797
        { ASARL,        yshl,   Px, 0xd1,(07),0xc1,(07),0xd3,(07),0xd3,(07) },
 
798
        { ASARW,        yshl,   Pe, 0xd1,(07),0xc1,(07),0xd3,(07),0xd3,(07) },
 
799
        { ASBBB,        yxorb,  Pb, 0x1c,0x80,(03),0x18,0x1a },
 
800
        { ASBBL,        yxorl,  Px, 0x83,(03),0x1d,0x81,(03),0x19,0x1b },
 
801
        { ASBBW,        yxorl,  Pe, 0x83,(03),0x1d,0x81,(03),0x19,0x1b },
 
802
        { ASCASB,       ynone,  Pb, 0xae },
 
803
        { ASCASL,       ynone,  Px, 0xaf },
 
804
        { ASCASW,       ynone,  Pe, 0xaf },
 
805
        { ASETCC,       yscond, Pm, 0x93,(00) },
 
806
        { ASETCS,       yscond, Pm, 0x92,(00) },
 
807
        { ASETEQ,       yscond, Pm, 0x94,(00) },
 
808
        { ASETGE,       yscond, Pm, 0x9d,(00) },
 
809
        { ASETGT,       yscond, Pm, 0x9f,(00) },
 
810
        { ASETHI,       yscond, Pm, 0x97,(00) },
 
811
        { ASETLE,       yscond, Pm, 0x9e,(00) },
 
812
        { ASETLS,       yscond, Pm, 0x96,(00) },
 
813
        { ASETLT,       yscond, Pm, 0x9c,(00) },
 
814
        { ASETMI,       yscond, Pm, 0x98,(00) },
 
815
        { ASETNE,       yscond, Pm, 0x95,(00) },
 
816
        { ASETOC,       yscond, Pm, 0x91,(00) },
 
817
        { ASETOS,       yscond, Pm, 0x90,(00) },
 
818
        { ASETPC,       yscond, Pm, 0x96,(00) },
 
819
        { ASETPL,       yscond, Pm, 0x99,(00) },
 
820
        { ASETPS,       yscond, Pm, 0x9a,(00) },
 
821
        { ACDQ,         ynone,  Px, 0x99 },
 
822
        { ACWD,         ynone,  Pe, 0x99 },
 
823
        { ASHLB,        yshb,   Pb, 0xd0,(04),0xc0,(04),0xd2,(04) },
 
824
        { ASHLL,        yshl,   Px, 0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04) },
 
825
        { ASHLW,        yshl,   Pe, 0xd1,(04),0xc1,(04),0xd3,(04),0xd3,(04) },
 
826
        { ASHRB,        yshb,   Pb, 0xd0,(05),0xc0,(05),0xd2,(05) },
 
827
        { ASHRL,        yshl,   Px, 0xd1,(05),0xc1,(05),0xd3,(05),0xd3,(05) },
 
828
        { ASHRW,        yshl,   Pe, 0xd1,(05),0xc1,(05),0xd3,(05),0xd3,(05) },
 
829
        { ASTC,         ynone,  Px, 0xf9 },
 
830
        { ASTD,         ynone,  Px, 0xfd },
 
831
        { ASTI,         ynone,  Px, 0xfb },
 
832
        { ASTOSB,       ynone,  Pb, 0xaa },
 
833
        { ASTOSL,       ynone,  Px, 0xab },
 
834
        { ASTOSW,       ynone,  Pe, 0xab },
 
835
        { ASUBB,        yxorb,  Pb, 0x2c,0x80,(05),0x28,0x2a },
 
836
        { ASUBL,        yaddl,  Px, 0x83,(05),0x2d,0x81,(05),0x29,0x2b },
 
837
        { ASUBW,        yaddl,  Pe, 0x83,(05),0x2d,0x81,(05),0x29,0x2b },
 
838
        { ASYSCALL,     ynone,  Px, 0xcd,100 },
 
839
        { ATESTB,       ytestb, Pb, 0xa8,0xf6,(00),0x84,0x84 },
 
840
        { ATESTL,       ytestl, Px, 0xa9,0xf7,(00),0x85,0x85 },
 
841
        { ATESTW,       ytestl, Pe, 0xa9,0xf7,(00),0x85,0x85 },
 
842
        { ATEXT,        ytext,  Px },
 
843
        { AVERR,        ydivl,  Pm, 0x00,(04) },
 
844
        { AVERW,        ydivl,  Pm, 0x00,(05) },
 
845
        { AWAIT,        ynone,  Px, 0x9b },
 
846
        { AWORD,        ybyte,  Px, 2 },
 
847
        { AXCHGB,       yml_mb, Pb, 0x86,0x86 },
 
848
        { AXCHGL,       yxchg,  Px, 0x90,0x90,0x87,0x87 },
 
849
        { AXCHGW,       yxchg,  Pe, 0x90,0x90,0x87,0x87 },
 
850
        { AXLAT,        ynone,  Px, 0xd7 },
 
851
        { AXORB,        yxorb,  Pb, 0x34,0x80,(06),0x30,0x32 },
 
852
        { AXORL,        yxorl,  Px, 0x83,(06),0x35,0x81,(06),0x31,0x33 },
 
853
        { AXORW,        yxorl,  Pe, 0x83,(06),0x35,0x81,(06),0x31,0x33 },
 
854
 
 
855
        { AFMOVB,       yfmvx,  Px, 0xdf,(04) },
 
856
        { AFMOVBP,      yfmvp,  Px, 0xdf,(06) },
 
857
        { AFMOVD,       yfmvd,  Px, 0xdd,(00),0xdd,(02),0xd9,(00),0xdd,(02) },
 
858
        { AFMOVDP,      yfmvdp, Px, 0xdd,(03),0xdd,(03) },
 
859
        { AFMOVF,       yfmvf,  Px, 0xd9,(00),0xd9,(02) },
 
860
        { AFMOVFP,      yfmvp,  Px, 0xd9,(03) },
 
861
        { AFMOVL,       yfmvf,  Px, 0xdb,(00),0xdb,(02) },
 
862
        { AFMOVLP,      yfmvp,  Px, 0xdb,(03) },
 
863
        { AFMOVV,       yfmvx,  Px, 0xdf,(05) },
 
864
        { AFMOVVP,      yfmvp,  Px, 0xdf,(07) },
 
865
        { AFMOVW,       yfmvf,  Px, 0xdf,(00),0xdf,(02) },
 
866
        { AFMOVWP,      yfmvp,  Px, 0xdf,(03) },
 
867
        { AFMOVX,       yfmvx,  Px, 0xdb,(05) },
 
868
        { AFMOVXP,      yfmvp,  Px, 0xdb,(07) },
 
869
 
 
870
        { AFCOMB },
 
871
        { AFCOMBP },
 
872
        { AFCOMD,       yfadd,  Px, 0xdc,(02),0xd8,(02),0xdc,(02) },    /* botch */
 
873
        { AFCOMDP,      yfadd,  Px, 0xdc,(03),0xd8,(03),0xdc,(03) },    /* botch */
 
874
        { AFCOMDPP,     ycompp, Px, 0xde,(03) },
 
875
        { AFCOMF,       yfmvx,  Px, 0xd8,(02) },
 
876
        { AFCOMFP,      yfmvx,  Px, 0xd8,(03) },
 
877
        { AFCOMI,       yfmvx,  Px, 0xdb,(06) },
 
878
        { AFCOMIP,      yfmvx,  Px, 0xdf,(06) },
 
879
        { AFCOML,       yfmvx,  Px, 0xda,(02) },
 
880
        { AFCOMLP,      yfmvx,  Px, 0xda,(03) },
 
881
        { AFCOMW,       yfmvx,  Px, 0xde,(02) },
 
882
        { AFCOMWP,      yfmvx,  Px, 0xde,(03) },
 
883
 
 
884
        { AFUCOM,       ycompp, Px, 0xdd,(04) },
 
885
        { AFUCOMI,      ycompp, Px, 0xdb,(05) },
 
886
        { AFUCOMIP,     ycompp, Px, 0xdf,(05) },
 
887
        { AFUCOMP,      ycompp, Px, 0xdd,(05) },
 
888
        { AFUCOMPP,     ycompp, Px, 0xda,(13) },
 
889
 
 
890
        { AFADDDP,      yfaddp, Px, 0xde,(00) },
 
891
        { AFADDW,       yfmvx,  Px, 0xde,(00) },
 
892
        { AFADDL,       yfmvx,  Px, 0xda,(00) },
 
893
        { AFADDF,       yfmvx,  Px, 0xd8,(00) },
 
894
        { AFADDD,       yfadd,  Px, 0xdc,(00),0xd8,(00),0xdc,(00) },
 
895
 
 
896
        { AFMULDP,      yfaddp, Px, 0xde,(01) },
 
897
        { AFMULW,       yfmvx,  Px, 0xde,(01) },
 
898
        { AFMULL,       yfmvx,  Px, 0xda,(01) },
 
899
        { AFMULF,       yfmvx,  Px, 0xd8,(01) },
 
900
        { AFMULD,       yfadd,  Px, 0xdc,(01),0xd8,(01),0xdc,(01) },
 
901
 
 
902
        { AFSUBDP,      yfaddp, Px, 0xde,(05) },
 
903
        { AFSUBW,       yfmvx,  Px, 0xde,(04) },
 
904
        { AFSUBL,       yfmvx,  Px, 0xda,(04) },
 
905
        { AFSUBF,       yfmvx,  Px, 0xd8,(04) },
 
906
        { AFSUBD,       yfadd,  Px, 0xdc,(04),0xd8,(04),0xdc,(05) },
 
907
 
 
908
        { AFSUBRDP,     yfaddp, Px, 0xde,(04) },
 
909
        { AFSUBRW,      yfmvx,  Px, 0xde,(05) },
 
910
        { AFSUBRL,      yfmvx,  Px, 0xda,(05) },
 
911
        { AFSUBRF,      yfmvx,  Px, 0xd8,(05) },
 
912
        { AFSUBRD,      yfadd,  Px, 0xdc,(05),0xd8,(05),0xdc,(04) },
 
913
 
 
914
        { AFDIVDP,      yfaddp, Px, 0xde,(07) },
 
915
        { AFDIVW,       yfmvx,  Px, 0xde,(06) },
 
916
        { AFDIVL,       yfmvx,  Px, 0xda,(06) },
 
917
        { AFDIVF,       yfmvx,  Px, 0xd8,(06) },
 
918
        { AFDIVD,       yfadd,  Px, 0xdc,(06),0xd8,(06),0xdc,(07) },
 
919
 
 
920
        { AFDIVRDP,     yfaddp, Px, 0xde,(06) },
 
921
        { AFDIVRW,      yfmvx,  Px, 0xde,(07) },
 
922
        { AFDIVRL,      yfmvx,  Px, 0xda,(07) },
 
923
        { AFDIVRF,      yfmvx,  Px, 0xd8,(07) },
 
924
        { AFDIVRD,      yfadd,  Px, 0xdc,(07),0xd8,(07),0xdc,(06) },
 
925
 
 
926
        { AFXCHD,       yfxch,  Px, 0xd9,(01),0xd9,(01) },
 
927
        { AFFREE },
 
928
        { AFLDCW,       ystcw,  Px, 0xd9,(05),0xd9,(05) },
 
929
        { AFLDENV,      ystcw,  Px, 0xd9,(04),0xd9,(04) },
 
930
        { AFRSTOR,      ysvrs,  Px, 0xdd,(04),0xdd,(04) },
 
931
        { AFSAVE,       ysvrs,  Px, 0xdd,(06),0xdd,(06) },
 
932
        { AFSTCW,       ystcw,  Px, 0xd9,(07),0xd9,(07) },
 
933
        { AFSTENV,      ystcw,  Px, 0xd9,(06),0xd9,(06) },
 
934
        { AFSTSW,       ystsw,  Px, 0xdd,(07),0xdf,0xe0 },
 
935
        { AF2XM1,       ynone,  Px, 0xd9, 0xf0 },
 
936
        { AFABS,        ynone,  Px, 0xd9, 0xe1 },
 
937
        { AFCHS,        ynone,  Px, 0xd9, 0xe0 },
 
938
        { AFCLEX,       ynone,  Px, 0xdb, 0xe2 },
 
939
        { AFCOS,        ynone,  Px, 0xd9, 0xff },
 
940
        { AFDECSTP,     ynone,  Px, 0xd9, 0xf6 },
 
941
        { AFINCSTP,     ynone,  Px, 0xd9, 0xf7 },
 
942
        { AFINIT,       ynone,  Px, 0xdb, 0xe3 },
 
943
        { AFLD1,        ynone,  Px, 0xd9, 0xe8 },
 
944
        { AFLDL2E,      ynone,  Px, 0xd9, 0xea },
 
945
        { AFLDL2T,      ynone,  Px, 0xd9, 0xe9 },
 
946
        { AFLDLG2,      ynone,  Px, 0xd9, 0xec },
 
947
        { AFLDLN2,      ynone,  Px, 0xd9, 0xed },
 
948
        { AFLDPI,       ynone,  Px, 0xd9, 0xeb },
 
949
        { AFLDZ,        ynone,  Px, 0xd9, 0xee },
 
950
        { AFNOP,        ynone,  Px, 0xd9, 0xd0 },
 
951
        { AFPATAN,      ynone,  Px, 0xd9, 0xf3 },
 
952
        { AFPREM,       ynone,  Px, 0xd9, 0xf8 },
 
953
        { AFPREM1,      ynone,  Px, 0xd9, 0xf5 },
 
954
        { AFPTAN,       ynone,  Px, 0xd9, 0xf2 },
 
955
        { AFRNDINT,     ynone,  Px, 0xd9, 0xfc },
 
956
        { AFSCALE,      ynone,  Px, 0xd9, 0xfd },
 
957
        { AFSIN,        ynone,  Px, 0xd9, 0xfe },
 
958
        { AFSINCOS,     ynone,  Px, 0xd9, 0xfb },
 
959
        { AFSQRT,       ynone,  Px, 0xd9, 0xfa },
 
960
        { AFTST,        ynone,  Px, 0xd9, 0xe4 },
 
961
        { AFXAM,        ynone,  Px, 0xd9, 0xe5 },
 
962
        { AFXTRACT,     ynone,  Px, 0xd9, 0xf4 },
 
963
        { AFYL2X,       ynone,  Px, 0xd9, 0xf1 },
 
964
        { AFYL2XP1,     ynone,  Px, 0xd9, 0xf9 },
 
965
        { AEND },
 
966
        { ADYNT_ },
 
967
        { AINIT_ },
 
968
        { ASIGNAME },
 
969
        { ACMPXCHGB,    yrb_mb, Pm, 0xb0 },
 
970
        { ACMPXCHGL,    yrl_ml, Pm, 0xb1 },
 
971
        { ACMPXCHGW,    yrl_ml, Pm, 0xb1 },
 
972
        { ACMPXCHG8B,   yscond, Pm, 0xc7,(01) },
 
973
 
 
974
        { ACPUID,       ynone,  Pm, 0xa2 },
 
975
        { ARDTSC,       ynone,  Pm, 0x31 },
 
976
 
 
977
        { AXADDB,       yrb_mb, Pb, 0x0f,0xc0 },
 
978
        { AXADDL,       yrl_ml, Pm, 0xc1 },
 
979
        { AXADDW,       yrl_ml, Pe, 0x0f,0xc1 },
 
980
 
 
981
        { ACMOVLCC,     yml_rl, Pm, 0x43 },
 
982
        { ACMOVLCS,     yml_rl, Pm, 0x42 },
 
983
        { ACMOVLEQ,     yml_rl, Pm, 0x44 },
 
984
        { ACMOVLGE,     yml_rl, Pm, 0x4d },
 
985
        { ACMOVLGT,     yml_rl, Pm, 0x4f },
 
986
        { ACMOVLHI,     yml_rl, Pm, 0x47 },
 
987
        { ACMOVLLE,     yml_rl, Pm, 0x4e },
 
988
        { ACMOVLLS,     yml_rl, Pm, 0x46 },
 
989
        { ACMOVLLT,     yml_rl, Pm, 0x4c },
 
990
        { ACMOVLMI,     yml_rl, Pm, 0x48 },
 
991
        { ACMOVLNE,     yml_rl, Pm, 0x45 },
 
992
        { ACMOVLOC,     yml_rl, Pm, 0x41 },
 
993
        { ACMOVLOS,     yml_rl, Pm, 0x40 },
 
994
        { ACMOVLPC,     yml_rl, Pm, 0x4b },
 
995
        { ACMOVLPL,     yml_rl, Pm, 0x49 },
 
996
        { ACMOVLPS,     yml_rl, Pm, 0x4a },
 
997
        { ACMOVWCC,     yml_rl, Pq, 0x43 },
 
998
        { ACMOVWCS,     yml_rl, Pq, 0x42 },
 
999
        { ACMOVWEQ,     yml_rl, Pq, 0x44 },
 
1000
        { ACMOVWGE,     yml_rl, Pq, 0x4d },
 
1001
        { ACMOVWGT,     yml_rl, Pq, 0x4f },
 
1002
        { ACMOVWHI,     yml_rl, Pq, 0x47 },
 
1003
        { ACMOVWLE,     yml_rl, Pq, 0x4e },
 
1004
        { ACMOVWLS,     yml_rl, Pq, 0x46 },
 
1005
        { ACMOVWLT,     yml_rl, Pq, 0x4c },
 
1006
        { ACMOVWMI,     yml_rl, Pq, 0x48 },
 
1007
        { ACMOVWNE,     yml_rl, Pq, 0x45 },
 
1008
        { ACMOVWOC,     yml_rl, Pq, 0x41 },
 
1009
        { ACMOVWOS,     yml_rl, Pq, 0x40 },
 
1010
        { ACMOVWPC,     yml_rl, Pq, 0x4b },
 
1011
        { ACMOVWPL,     yml_rl, Pq, 0x49 },
 
1012
        { ACMOVWPS,     yml_rl, Pq, 0x4a },
 
1013
 
 
1014
        { AFCMOVCC,     yfcmv,  Px, 0xdb,(00) },
 
1015
        { AFCMOVCS,     yfcmv,  Px, 0xda,(00) },
 
1016
        { AFCMOVEQ,     yfcmv,  Px, 0xda,(01) },
 
1017
        { AFCMOVHI,     yfcmv,  Px, 0xdb,(02) },
 
1018
        { AFCMOVLS,     yfcmv,  Px, 0xda,(02) },
 
1019
        { AFCMOVNE,     yfcmv,  Px, 0xdb,(01) },
 
1020
        { AFCMOVNU,     yfcmv,  Px, 0xdb,(03) },
 
1021
        { AFCMOVUN,     yfcmv,  Px, 0xda,(03) },
 
1022
 
 
1023
        { ALFENCE, ynone, Pm, 0xae,0xe8 },
 
1024
        { AMFENCE, ynone, Pm, 0xae,0xf0 },
 
1025
        { ASFENCE, ynone, Pm, 0xae,0xf8 },
 
1026
 
 
1027
        { AEMMS, ynone, Pm, 0x77 },
 
1028
 
 
1029
        { APREFETCHT0,  yprefetch,      Pm,     0x18,(01) },
 
1030
        { APREFETCHT1,  yprefetch,      Pm,     0x18,(02) },
 
1031
        { APREFETCHT2,  yprefetch,      Pm,     0x18,(03) },
 
1032
        { APREFETCHNTA, yprefetch,      Pm,     0x18,(00) },
 
1033
 
 
1034
        { ABSWAPL,      ybswap, Pm,     0xc8 },
 
1035
        
 
1036
        { AUNDEF,               ynone,  Px,     0x0f, 0x0b },
 
1037
 
 
1038
        { AADDPD,       yxm,    Pq, 0x58 },
 
1039
        { AADDPS,       yxm,    Pm, 0x58 },
 
1040
        { AADDSD,       yxm,    Pf2, 0x58 },
 
1041
        { AADDSS,       yxm,    Pf3, 0x58 },
 
1042
        { AANDNPD,      yxm,    Pq, 0x55 },
 
1043
        { AANDNPS,      yxm,    Pm, 0x55 },
 
1044
        { AANDPD,       yxm,    Pq, 0x54 },
 
1045
        { AANDPS,       yxm,    Pq, 0x54 },
 
1046
        { ACMPPD,       yxcmpi, Px, Pe,0xc2 },
 
1047
        { ACMPPS,       yxcmpi, Pm, 0xc2,0 },
 
1048
        { ACMPSD,       yxcmpi, Px, Pf2,0xc2 },
 
1049
        { ACMPSS,       yxcmpi, Px, Pf3,0xc2 },
 
1050
        { ACOMISD,      yxcmp,  Pe, 0x2f },
 
1051
        { ACOMISS,      yxcmp,  Pm, 0x2f },
 
1052
        { ACVTPL2PD,    yxcvm2, Px, Pf3,0xe6,Pe,0x2a },
 
1053
        { ACVTPL2PS,    yxcvm2, Pm, 0x5b,0,0x2a,0, },
 
1054
        { ACVTPD2PL,    yxcvm1, Px, Pf2,0xe6,Pe,0x2d },
 
1055
        { ACVTPD2PS,    yxm,    Pe, 0x5a },
 
1056
        { ACVTPS2PL,    yxcvm1, Px, Pe,0x5b,Pm,0x2d },
 
1057
        { ACVTPS2PD,    yxm,    Pm, 0x5a },
 
1058
        { ACVTSD2SL,    yxcvfl, Pf2, 0x2d },
 
1059
        { ACVTSD2SS,    yxm,    Pf2, 0x5a },
 
1060
        { ACVTSL2SD,    yxcvlf, Pf2, 0x2a },
 
1061
        { ACVTSL2SS,    yxcvlf, Pf3, 0x2a },
 
1062
        { ACVTSS2SD,    yxm,    Pf3, 0x5a },
 
1063
        { ACVTSS2SL,    yxcvfl, Pf3, 0x2d },
 
1064
        { ACVTTPD2PL,   yxcvm1, Px, Pe,0xe6,Pe,0x2c },
 
1065
        { ACVTTPS2PL,   yxcvm1, Px, Pf3,0x5b,Pm,0x2c },
 
1066
        { ACVTTSD2SL,   yxcvfl, Pf2, 0x2c },
 
1067
        { ACVTTSS2SL,   yxcvfl, Pf3, 0x2c },
 
1068
        { ADIVPD,       yxm,    Pe, 0x5e },
 
1069
        { ADIVPS,       yxm,    Pm, 0x5e },
 
1070
        { ADIVSD,       yxm,    Pf2, 0x5e },
 
1071
        { ADIVSS,       yxm,    Pf3, 0x5e },
 
1072
        { AMASKMOVOU,   yxr,    Pe, 0xf7 },
 
1073
        { AMAXPD,       yxm,    Pe, 0x5f },
 
1074
        { AMAXPS,       yxm,    Pm, 0x5f },
 
1075
        { AMAXSD,       yxm,    Pf2, 0x5f },
 
1076
        { AMAXSS,       yxm,    Pf3, 0x5f },
 
1077
        { AMINPD,       yxm,    Pe, 0x5d },
 
1078
        { AMINPS,       yxm,    Pm, 0x5d },
 
1079
        { AMINSD,       yxm,    Pf2, 0x5d },
 
1080
        { AMINSS,       yxm,    Pf3, 0x5d },
 
1081
        { AMOVAPD,      yxmov,  Pe, 0x28,0x29 },
 
1082
        { AMOVAPS,      yxmov,  Pm, 0x28,0x29 },
 
1083
        { AMOVO,        yxmov,  Pe, 0x6f,0x7f },
 
1084
        { AMOVOU,       yxmov,  Pf3, 0x6f,0x7f },
 
1085
        { AMOVHLPS,     yxr,    Pm, 0x12 },
 
1086
        { AMOVHPD,      yxmov,  Pe, 0x16,0x17 },
 
1087
        { AMOVHPS,      yxmov,  Pm, 0x16,0x17 },
 
1088
        { AMOVLHPS,     yxr,    Pm, 0x16 },
 
1089
        { AMOVLPD,      yxmov,  Pe, 0x12,0x13 },
 
1090
        { AMOVLPS,      yxmov,  Pm, 0x12,0x13 },
 
1091
        { AMOVMSKPD,    yxrrl,  Pq, 0x50 },
 
1092
        { AMOVMSKPS,    yxrrl,  Pm, 0x50 },
 
1093
        { AMOVNTO,      yxr_ml, Pe, 0xe7 },
 
1094
        { AMOVNTPD,     yxr_ml, Pe, 0x2b },
 
1095
        { AMOVNTPS,     yxr_ml, Pm, 0x2b },
 
1096
        { AMOVSD,       yxmov,  Pf2, 0x10,0x11 },
 
1097
        { AMOVSS,       yxmov,  Pf3, 0x10,0x11 },
 
1098
        { AMOVUPD,      yxmov,  Pe, 0x10,0x11 },
 
1099
        { AMOVUPS,      yxmov,  Pm, 0x10,0x11 },
 
1100
        { AMULPD,       yxm,    Pe, 0x59 },
 
1101
        { AMULPS,       yxm,    Ym, 0x59 },
 
1102
        { AMULSD,       yxm,    Pf2, 0x59 },
 
1103
        { AMULSS,       yxm,    Pf3, 0x59 },
 
1104
        { AORPD,        yxm,    Pq, 0x56 },
 
1105
        { AORPS,        yxm,    Pm, 0x56 },
 
1106
        { APADDQ,       yxm,    Pe, 0xd4 },
 
1107
        { APAND,        yxm,    Pe, 0xdb },
 
1108
        { APCMPEQB,     yxmq,   Pe ,0x74 },
 
1109
        { APMAXSW,      yxm,    Pe, 0xee },
 
1110
        { APMAXUB,      yxm,    Pe, 0xde },
 
1111
        { APMINSW,      yxm,    Pe, 0xea },
 
1112
        { APMINUB,      yxm,    Pe, 0xda },
 
1113
        { APMOVMSKB,    ymskb,  Px, Pe,0xd7,0xd7 },
 
1114
        { APSADBW,      yxm,    Pq, 0xf6 },
 
1115
        { APSUBB,       yxm,    Pe, 0xf8 },
 
1116
        { APSUBL,       yxm,    Pe, 0xfa },
 
1117
        { APSUBQ,       yxm,    Pe, 0xfb },
 
1118
        { APSUBSB,      yxm,    Pe, 0xe8 },
 
1119
        { APSUBSW,      yxm,    Pe, 0xe9 },
 
1120
        { APSUBUSB,     yxm,    Pe, 0xd8 },
 
1121
        { APSUBUSW,     yxm,    Pe, 0xd9 },
 
1122
        { APSUBW,       yxm,    Pe, 0xf9 },
 
1123
        { APUNPCKHQDQ,  yxm,    Pe, 0x6d },
 
1124
        { APUNPCKLQDQ,  yxm,    Pe, 0x6c },
 
1125
        { APXOR,        yxm,    Pe, 0xef },
 
1126
        { ARCPPS,       yxm,    Pm, 0x53 },
 
1127
        { ARCPSS,       yxm,    Pf3, 0x53 },
 
1128
        { ARSQRTPS,     yxm,    Pm, 0x52 },
 
1129
        { ARSQRTSS,     yxm,    Pf3, 0x52 },
 
1130
        { ASQRTPD,      yxm,    Pe, 0x51 },
 
1131
        { ASQRTPS,      yxm,    Pm, 0x51 },
 
1132
        { ASQRTSD,      yxm,    Pf2, 0x51 },
 
1133
        { ASQRTSS,      yxm,    Pf3, 0x51 },
 
1134
        { ASUBPD,       yxm,    Pe, 0x5c },
 
1135
        { ASUBPS,       yxm,    Pm, 0x5c },
 
1136
        { ASUBSD,       yxm,    Pf2, 0x5c },
 
1137
        { ASUBSS,       yxm,    Pf3, 0x5c },
 
1138
        { AUCOMISD,     yxcmp,  Pe, 0x2e },
 
1139
        { AUCOMISS,     yxcmp,  Pm, 0x2e },
 
1140
        { AUNPCKHPD,    yxm,    Pe, 0x15 },
 
1141
        { AUNPCKHPS,    yxm,    Pm, 0x15 },
 
1142
        { AUNPCKLPD,    yxm,    Pe, 0x14 },
 
1143
        { AUNPCKLPS,    yxm,    Pm, 0x14 },
 
1144
        { AXORPD,       yxm,    Pe, 0x57 },
 
1145
        { AXORPS,       yxm,    Pm, 0x57 },
 
1146
 
 
1147
        { AAESENC,      yaes,   Pq, 0x38,0xdc,(0) },
 
1148
        { APINSRD,      yinsrd, Pq, 0x3a, 0x22, (00) },
 
1149
        { APSHUFB,      ymshufb,Pq, 0x38, 0x00 },
 
1150
 
 
1151
        { AUSEFIELD,    ynop,   Px, 0,0 },
 
1152
        { ATYPE },
 
1153
        { AFUNCDATA,    yfuncdata,      Px, 0,0 },
 
1154
        { APCDATA,      ypcdata,        Px, 0,0 },
 
1155
        { ACHECKNIL },
 
1156
        { AVARDEF },
 
1157
        { AVARKILL },
 
1158
        { ADUFFCOPY,    yduff,  Px, 0xe8 },
 
1159
        { ADUFFZERO,    yduff,  Px, 0xe8 },
 
1160
 
 
1161
        0
 
1162
};
 
1163
 
 
1164
static int32    vaddr(Link*, Addr*, Reloc*);
 
1165
 
 
1166
// single-instruction no-ops of various lengths.
 
1167
// constructed by hand and disassembled with gdb to verify.
 
1168
// see http://www.agner.org/optimize/optimizing_assembly.pdf for discussion.
 
1169
static uchar nop[][16] = {
 
1170
        {0x90},
 
1171
        {0x66, 0x90},
 
1172
        {0x0F, 0x1F, 0x00},
 
1173
        {0x0F, 0x1F, 0x40, 0x00},
 
1174
        {0x0F, 0x1F, 0x44, 0x00, 0x00},
 
1175
        {0x66, 0x0F, 0x1F, 0x44, 0x00, 0x00},
 
1176
        {0x0F, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00},
 
1177
        {0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
 
1178
        {0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
 
1179
        // Native Client rejects the repeated 0x66 prefix.
 
1180
        // {0x66, 0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00},
 
1181
};
 
1182
 
 
1183
static void
 
1184
fillnop(uchar *p, int n)
 
1185
{
 
1186
        int m;
 
1187
 
 
1188
        while(n > 0) {
 
1189
                m = n;
 
1190
                if(m > nelem(nop))
 
1191
                        m = nelem(nop);
 
1192
                memmove(p, nop[m-1], m);
 
1193
                p += m;
 
1194
                n -= m;
 
1195
        }
 
1196
}
 
1197
 
 
1198
static int32
 
1199
naclpad(Link *ctxt, LSym *s, int32 c, int32 pad)
 
1200
{
 
1201
        symgrow(ctxt, s, c+pad);
 
1202
        fillnop(s->p+c, pad);
 
1203
        return c+pad;
 
1204
}
 
1205
 
 
1206
static void instinit(void);
 
1207
 
 
1208
void
 
1209
span8(Link *ctxt, LSym *s)
 
1210
{
 
1211
        Prog *p, *q;
 
1212
        int32 c, v, loop;
 
1213
        uchar *bp;
 
1214
        int n, m, i;
 
1215
 
 
1216
        ctxt->cursym = s;
 
1217
 
 
1218
        if(s->text == nil || s->text->link == nil)
 
1219
                return;
 
1220
 
 
1221
        if(ycover[0] == 0)
 
1222
                instinit();
 
1223
 
 
1224
        for(p = s->text; p != nil; p = p->link) {
 
1225
                n = 0;
 
1226
                if(p->to.type == D_BRANCH)
 
1227
                        if(p->pcond == nil)
 
1228
                                p->pcond = p;
 
1229
                if((q = p->pcond) != nil)
 
1230
                        if(q->back != 2)
 
1231
                                n = 1;
 
1232
                p->back = n;
 
1233
                if(p->as == AADJSP) {
 
1234
                        p->to.type = D_SP;
 
1235
                        v = -p->from.offset;
 
1236
                        p->from.offset = v;
 
1237
                        p->as = AADDL;
 
1238
                        if(v < 0) {
 
1239
                                p->as = ASUBL;
 
1240
                                v = -v;
 
1241
                                p->from.offset = v;
 
1242
                        }
 
1243
                        if(v == 0)
 
1244
                                p->as = ANOP;
 
1245
                }
 
1246
        }
 
1247
 
 
1248
        for(p = s->text; p != nil; p = p->link) {
 
1249
                p->back = 2;    // use short branches first time through
 
1250
                if((q = p->pcond) != nil && (q->back & 2))
 
1251
                        p->back |= 1;   // backward jump
 
1252
 
 
1253
                if(p->as == AADJSP) {
 
1254
                        p->to.type = D_SP;
 
1255
                        v = -p->from.offset;
 
1256
                        p->from.offset = v;
 
1257
                        p->as = AADDL;
 
1258
                        if(v < 0) {
 
1259
                                p->as = ASUBL;
 
1260
                                v = -v;
 
1261
                                p->from.offset = v;
 
1262
                        }
 
1263
                        if(v == 0)
 
1264
                                p->as = ANOP;
 
1265
                }
 
1266
        }
 
1267
        
 
1268
        n = 0;
 
1269
        do {
 
1270
                loop = 0;
 
1271
                memset(s->r, 0, s->nr*sizeof s->r[0]);
 
1272
                s->nr = 0;
 
1273
                s->np = 0;
 
1274
                c = 0;
 
1275
                for(p = s->text; p != nil; p = p->link) {
 
1276
                        if(ctxt->headtype == Hnacl && p->isize > 0) {
 
1277
                                static LSym *deferreturn;
 
1278
                                
 
1279
                                if(deferreturn == nil)
 
1280
                                        deferreturn = linklookup(ctxt, "runtime.deferreturn", 0);
 
1281
 
 
1282
                                // pad everything to avoid crossing 32-byte boundary
 
1283
                                if((c>>5) != ((c+p->isize-1)>>5))
 
1284
                                        c = naclpad(ctxt, s, c, -c&31);
 
1285
                                // pad call deferreturn to start at 32-byte boundary
 
1286
                                // so that subtracting 5 in jmpdefer will jump back
 
1287
                                // to that boundary and rerun the call.
 
1288
                                if(p->as == ACALL && p->to.sym == deferreturn)
 
1289
                                        c = naclpad(ctxt, s, c, -c&31);
 
1290
                                // pad call to end at 32-byte boundary
 
1291
                                if(p->as == ACALL)
 
1292
                                        c = naclpad(ctxt, s, c, -(c+p->isize)&31);
 
1293
                                
 
1294
                                // the linker treats REP and STOSQ as different instructions
 
1295
                                // but in fact the REP is a prefix on the STOSQ.
 
1296
                                // make sure REP has room for 2 more bytes, so that
 
1297
                                // padding will not be inserted before the next instruction.
 
1298
                                if(p->as == AREP && (c>>5) != ((c+3-1)>>5))
 
1299
                                        c = naclpad(ctxt, s, c, -c&31);
 
1300
                                
 
1301
                                // same for LOCK.
 
1302
                                // various instructions follow; the longest is 4 bytes.
 
1303
                                // give ourselves 8 bytes so as to avoid surprises.
 
1304
                                if(p->as == ALOCK && (c>>5) != ((c+8-1)>>5))
 
1305
                                        c = naclpad(ctxt, s, c, -c&31);
 
1306
                        }
 
1307
                        
 
1308
                        p->pc = c;
 
1309
 
 
1310
                        // process forward jumps to p
 
1311
                        for(q = p->comefrom; q != nil; q = q->forwd) {
 
1312
                                v = p->pc - (q->pc + q->mark);
 
1313
                                if(q->back & 2) {       // short
 
1314
                                        if(v > 127) {
 
1315
                                                loop++;
 
1316
                                                q->back ^= 2;
 
1317
                                        }
 
1318
                                        if(q->as == AJCXZW)
 
1319
                                                s->p[q->pc+2] = v;
 
1320
                                        else
 
1321
                                                s->p[q->pc+1] = v;
 
1322
                                } else {
 
1323
                                        bp = s->p + q->pc + q->mark - 4;
 
1324
                                        *bp++ = v;
 
1325
                                        *bp++ = v>>8;
 
1326
                                        *bp++ = v>>16;
 
1327
                                        *bp = v>>24;
 
1328
                                }       
 
1329
                        }
 
1330
                        p->comefrom = nil;
 
1331
 
 
1332
                        p->pc = c;
 
1333
                        asmins(ctxt, p);
 
1334
                        m = ctxt->andptr-ctxt->and;
 
1335
                        if(p->isize != m) {
 
1336
                                p->isize = m;
 
1337
                                loop++;
 
1338
                        }
 
1339
                        symgrow(ctxt, s, p->pc+m);
 
1340
                        memmove(s->p+p->pc, ctxt->and, m);
 
1341
                        p->mark = m;
 
1342
                        c += m;
 
1343
                }
 
1344
                if(++n > 20) {
 
1345
                        ctxt->diag("span must be looping");
 
1346
                        sysfatal("bad code");
 
1347
                }
 
1348
        } while(loop);
 
1349
        
 
1350
        if(ctxt->headtype == Hnacl)
 
1351
                c = naclpad(ctxt, s, c, -c&31);
 
1352
        c += -c&(FuncAlign-1);
 
1353
        s->size = c;
 
1354
 
 
1355
        if(0 /* debug['a'] > 1 */) {
 
1356
                print("span1 %s %lld (%d tries)\n %.6ux", s->name, s->size, n, 0);
 
1357
                for(i=0; i<s->np; i++) {
 
1358
                        print(" %.2ux", s->p[i]);
 
1359
                        if(i%16 == 15)
 
1360
                                print("\n  %.6ux", i+1);
 
1361
                }
 
1362
                if(i%16)
 
1363
                        print("\n");
 
1364
        
 
1365
                for(i=0; i<s->nr; i++) {
 
1366
                        Reloc *r;
 
1367
                        
 
1368
                        r = &s->r[i];
 
1369
                        print(" rel %#.4ux/%d %s%+lld\n", r->off, r->siz, r->sym->name, r->add);
 
1370
                }
 
1371
        }
 
1372
}
 
1373
 
 
1374
static void
 
1375
instinit(void)
 
1376
{
 
1377
        int i;
 
1378
 
 
1379
        for(i=1; optab[i].as; i++)
 
1380
                if(i != optab[i].as)
 
1381
                        sysfatal("phase error in optab: at %A found %A", i, optab[i].as);
 
1382
 
 
1383
        for(i=0; i<Ymax; i++)
 
1384
                ycover[i*Ymax + i] = 1;
 
1385
 
 
1386
        ycover[Yi0*Ymax + Yi8] = 1;
 
1387
        ycover[Yi1*Ymax + Yi8] = 1;
 
1388
 
 
1389
        ycover[Yi0*Ymax + Yi32] = 1;
 
1390
        ycover[Yi1*Ymax + Yi32] = 1;
 
1391
        ycover[Yi8*Ymax + Yi32] = 1;
 
1392
 
 
1393
        ycover[Yal*Ymax + Yrb] = 1;
 
1394
        ycover[Ycl*Ymax + Yrb] = 1;
 
1395
        ycover[Yax*Ymax + Yrb] = 1;
 
1396
        ycover[Ycx*Ymax + Yrb] = 1;
 
1397
        ycover[Yrx*Ymax + Yrb] = 1;
 
1398
 
 
1399
        ycover[Yax*Ymax + Yrx] = 1;
 
1400
        ycover[Ycx*Ymax + Yrx] = 1;
 
1401
 
 
1402
        ycover[Yax*Ymax + Yrl] = 1;
 
1403
        ycover[Ycx*Ymax + Yrl] = 1;
 
1404
        ycover[Yrx*Ymax + Yrl] = 1;
 
1405
 
 
1406
        ycover[Yf0*Ymax + Yrf] = 1;
 
1407
 
 
1408
        ycover[Yal*Ymax + Ymb] = 1;
 
1409
        ycover[Ycl*Ymax + Ymb] = 1;
 
1410
        ycover[Yax*Ymax + Ymb] = 1;
 
1411
        ycover[Ycx*Ymax + Ymb] = 1;
 
1412
        ycover[Yrx*Ymax + Ymb] = 1;
 
1413
        ycover[Yrb*Ymax + Ymb] = 1;
 
1414
        ycover[Ym*Ymax + Ymb] = 1;
 
1415
 
 
1416
        ycover[Yax*Ymax + Yml] = 1;
 
1417
        ycover[Ycx*Ymax + Yml] = 1;
 
1418
        ycover[Yrx*Ymax + Yml] = 1;
 
1419
        ycover[Yrl*Ymax + Yml] = 1;
 
1420
        ycover[Ym*Ymax + Yml] = 1;
 
1421
 
 
1422
        ycover[Yax*Ymax + Ymm] = 1;
 
1423
        ycover[Ycx*Ymax + Ymm] = 1;
 
1424
        ycover[Yrx*Ymax + Ymm] = 1;
 
1425
        ycover[Yrl*Ymax + Ymm] = 1;
 
1426
        ycover[Ym*Ymax + Ymm] = 1;
 
1427
        ycover[Ymr*Ymax + Ymm] = 1;
 
1428
 
 
1429
        ycover[Ym*Ymax + Yxm] = 1;
 
1430
        ycover[Yxr*Ymax + Yxm] = 1;
 
1431
 
 
1432
        for(i=0; i<D_NONE; i++) {
 
1433
                reg[i] = -1;
 
1434
                if(i >= D_AL && i <= D_BH)
 
1435
                        reg[i] = (i-D_AL) & 7;
 
1436
                if(i >= D_AX && i <= D_DI)
 
1437
                        reg[i] = (i-D_AX) & 7;
 
1438
                if(i >= D_F0 && i <= D_F0+7)
 
1439
                        reg[i] = (i-D_F0) & 7;
 
1440
                if(i >= D_X0 && i <= D_X0+7)
 
1441
                        reg[i] = (i-D_X0) & 7;
 
1442
        }
 
1443
}
 
1444
 
 
1445
static int
 
1446
prefixof(Link *ctxt, Addr *a)
 
1447
{
 
1448
        switch(a->type) {
 
1449
        case D_INDIR+D_CS:
 
1450
                return 0x2e;
 
1451
        case D_INDIR+D_DS:
 
1452
                return 0x3e;
 
1453
        case D_INDIR+D_ES:
 
1454
                return 0x26;
 
1455
        case D_INDIR+D_FS:
 
1456
                return 0x64;
 
1457
        case D_INDIR+D_GS:
 
1458
                return 0x65;
 
1459
        case D_INDIR+D_TLS:
 
1460
                // NOTE: Systems listed here should be only systems that
 
1461
                // support direct TLS references like 8(TLS) implemented as
 
1462
                // direct references from FS or GS. Systems that require
 
1463
                // the initial-exec model, where you load the TLS base into
 
1464
                // a register and then index from that register, do not reach
 
1465
                // this code and should not be listed.
 
1466
                switch(ctxt->headtype) {
 
1467
                default:
 
1468
                        sysfatal("unknown TLS base register for %s", headstr(ctxt->headtype));
 
1469
                case Hdarwin:
 
1470
                case Hdragonfly:
 
1471
                case Hfreebsd:
 
1472
                case Hnetbsd:
 
1473
                case Hopenbsd:
 
1474
                        return 0x65; // GS
 
1475
                }
 
1476
        }
 
1477
        return 0;
 
1478
}
 
1479
 
 
1480
static int
 
1481
oclass(Addr *a)
 
1482
{
 
1483
        int32 v;
 
1484
 
 
1485
        if((a->type >= D_INDIR && a->type < 2*D_INDIR) || a->index != D_NONE) {
 
1486
                if(a->index != D_NONE && a->scale == 0) {
 
1487
                        if(a->type == D_ADDR) {
 
1488
                                switch(a->index) {
 
1489
                                case D_EXTERN:
 
1490
                                case D_STATIC:
 
1491
                                        return Yi32;
 
1492
                                case D_AUTO:
 
1493
                                case D_PARAM:
 
1494
                                        return Yiauto;
 
1495
                                }
 
1496
                                return Yxxx;
 
1497
                        }
 
1498
                        //if(a->type == D_INDIR+D_ADDR)
 
1499
                        //      print("*Ycol\n");
 
1500
                        return Ycol;
 
1501
                }
 
1502
                return Ym;
 
1503
        }
 
1504
        switch(a->type)
 
1505
        {
 
1506
        case D_AL:
 
1507
                return Yal;
 
1508
 
 
1509
        case D_AX:
 
1510
                return Yax;
 
1511
 
 
1512
        case D_CL:
 
1513
        case D_DL:
 
1514
        case D_BL:
 
1515
        case D_AH:
 
1516
        case D_CH:
 
1517
        case D_DH:
 
1518
        case D_BH:
 
1519
                return Yrb;
 
1520
 
 
1521
        case D_CX:
 
1522
                return Ycx;
 
1523
 
 
1524
        case D_DX:
 
1525
        case D_BX:
 
1526
                return Yrx;
 
1527
 
 
1528
        case D_SP:
 
1529
        case D_BP:
 
1530
        case D_SI:
 
1531
        case D_DI:
 
1532
                return Yrl;
 
1533
 
 
1534
        case D_F0+0:
 
1535
                return  Yf0;
 
1536
 
 
1537
        case D_F0+1:
 
1538
        case D_F0+2:
 
1539
        case D_F0+3:
 
1540
        case D_F0+4:
 
1541
        case D_F0+5:
 
1542
        case D_F0+6:
 
1543
        case D_F0+7:
 
1544
                return  Yrf;
 
1545
 
 
1546
        case D_X0+0:
 
1547
        case D_X0+1:
 
1548
        case D_X0+2:
 
1549
        case D_X0+3:
 
1550
        case D_X0+4:
 
1551
        case D_X0+5:
 
1552
        case D_X0+6:
 
1553
        case D_X0+7:
 
1554
                return  Yxr;
 
1555
 
 
1556
        case D_NONE:
 
1557
                return Ynone;
 
1558
 
 
1559
        case D_CS:      return  Ycs;
 
1560
        case D_SS:      return  Yss;
 
1561
        case D_DS:      return  Yds;
 
1562
        case D_ES:      return  Yes;
 
1563
        case D_FS:      return  Yfs;
 
1564
        case D_GS:      return  Ygs;
 
1565
        case D_TLS:     return  Ytls;
 
1566
 
 
1567
        case D_GDTR:    return  Ygdtr;
 
1568
        case D_IDTR:    return  Yidtr;
 
1569
        case D_LDTR:    return  Yldtr;
 
1570
        case D_MSW:     return  Ymsw;
 
1571
        case D_TASK:    return  Ytask;
 
1572
 
 
1573
        case D_CR+0:    return  Ycr0;
 
1574
        case D_CR+1:    return  Ycr1;
 
1575
        case D_CR+2:    return  Ycr2;
 
1576
        case D_CR+3:    return  Ycr3;
 
1577
        case D_CR+4:    return  Ycr4;
 
1578
        case D_CR+5:    return  Ycr5;
 
1579
        case D_CR+6:    return  Ycr6;
 
1580
        case D_CR+7:    return  Ycr7;
 
1581
 
 
1582
        case D_DR+0:    return  Ydr0;
 
1583
        case D_DR+1:    return  Ydr1;
 
1584
        case D_DR+2:    return  Ydr2;
 
1585
        case D_DR+3:    return  Ydr3;
 
1586
        case D_DR+4:    return  Ydr4;
 
1587
        case D_DR+5:    return  Ydr5;
 
1588
        case D_DR+6:    return  Ydr6;
 
1589
        case D_DR+7:    return  Ydr7;
 
1590
 
 
1591
        case D_TR+0:    return  Ytr0;
 
1592
        case D_TR+1:    return  Ytr1;
 
1593
        case D_TR+2:    return  Ytr2;
 
1594
        case D_TR+3:    return  Ytr3;
 
1595
        case D_TR+4:    return  Ytr4;
 
1596
        case D_TR+5:    return  Ytr5;
 
1597
        case D_TR+6:    return  Ytr6;
 
1598
        case D_TR+7:    return  Ytr7;
 
1599
 
 
1600
        case D_EXTERN:
 
1601
        case D_STATIC:
 
1602
        case D_AUTO:
 
1603
        case D_PARAM:
 
1604
                return Ym;
 
1605
 
 
1606
        case D_CONST:
 
1607
        case D_CONST2:
 
1608
        case D_ADDR:
 
1609
                if(a->sym == nil) {
 
1610
                        v = a->offset;
 
1611
                        if(v == 0)
 
1612
                                return Yi0;
 
1613
                        if(v == 1)
 
1614
                                return Yi1;
 
1615
                        if(v >= -128 && v <= 127)
 
1616
                                return Yi8;
 
1617
                }
 
1618
                return Yi32;
 
1619
 
 
1620
        case D_BRANCH:
 
1621
                return Ybr;
 
1622
        }
 
1623
        return Yxxx;
 
1624
}
 
1625
 
 
1626
static void
 
1627
asmidx(Link *ctxt, int scale, int index, int base)
 
1628
{
 
1629
        int i;
 
1630
 
 
1631
        switch(index) {
 
1632
        default:
 
1633
                goto bad;
 
1634
 
 
1635
        case D_NONE:
 
1636
                i = 4 << 3;
 
1637
                goto bas;
 
1638
 
 
1639
        case D_AX:
 
1640
        case D_CX:
 
1641
        case D_DX:
 
1642
        case D_BX:
 
1643
        case D_BP:
 
1644
        case D_SI:
 
1645
        case D_DI:
 
1646
                i = reg[index] << 3;
 
1647
                break;
 
1648
        }
 
1649
        switch(scale) {
 
1650
        default:
 
1651
                goto bad;
 
1652
        case 1:
 
1653
                break;
 
1654
        case 2:
 
1655
                i |= (1<<6);
 
1656
                break;
 
1657
        case 4:
 
1658
                i |= (2<<6);
 
1659
                break;
 
1660
        case 8:
 
1661
                i |= (3<<6);
 
1662
                break;
 
1663
        }
 
1664
bas:
 
1665
        switch(base) {
 
1666
        default:
 
1667
                goto bad;
 
1668
        case D_NONE:    /* must be mod=00 */
 
1669
                i |= 5;
 
1670
                break;
 
1671
        case D_AX:
 
1672
        case D_CX:
 
1673
        case D_DX:
 
1674
        case D_BX:
 
1675
        case D_SP:
 
1676
        case D_BP:
 
1677
        case D_SI:
 
1678
        case D_DI:
 
1679
                i |= reg[base];
 
1680
                break;
 
1681
        }
 
1682
        *ctxt->andptr++ = i;
 
1683
        return;
 
1684
bad:
 
1685
        ctxt->diag("asmidx: bad address %d,%d,%d", scale, index, base);
 
1686
        *ctxt->andptr++ = 0;
 
1687
        return;
 
1688
}
 
1689
 
 
1690
static void
 
1691
put4(Link *ctxt, int32 v)
 
1692
{
 
1693
        ctxt->andptr[0] = v;
 
1694
        ctxt->andptr[1] = v>>8;
 
1695
        ctxt->andptr[2] = v>>16;
 
1696
        ctxt->andptr[3] = v>>24;
 
1697
        ctxt->andptr += 4;
 
1698
}
 
1699
 
 
1700
static void
 
1701
relput4(Link *ctxt, Prog *p, Addr *a)
 
1702
{
 
1703
        vlong v;
 
1704
        Reloc rel, *r;
 
1705
        
 
1706
        v = vaddr(ctxt, a, &rel);
 
1707
        if(rel.siz != 0) {
 
1708
                if(rel.siz != 4)
 
1709
                        ctxt->diag("bad reloc");
 
1710
                r = addrel(ctxt->cursym);
 
1711
                *r = rel;
 
1712
                r->off = p->pc + ctxt->andptr - ctxt->and;
 
1713
        }
 
1714
        put4(ctxt, v);
 
1715
}
 
1716
 
 
1717
static int32
 
1718
vaddr(Link *ctxt, Addr *a, Reloc *r)
 
1719
{
 
1720
        int t;
 
1721
        int32 v;
 
1722
        LSym *s;
 
1723
        
 
1724
        if(r != nil)
 
1725
                memset(r, 0, sizeof *r);
 
1726
 
 
1727
        t = a->type;
 
1728
        v = a->offset;
 
1729
        if(t == D_ADDR)
 
1730
                t = a->index;
 
1731
        switch(t) {
 
1732
        case D_STATIC:
 
1733
        case D_EXTERN:
 
1734
                s = a->sym;
 
1735
                if(s != nil) {
 
1736
                        if(r == nil) {
 
1737
                                ctxt->diag("need reloc for %D", a);
 
1738
                                sysfatal("bad code");
 
1739
                        }
 
1740
                        r->type = R_ADDR;
 
1741
                        r->siz = 4;
 
1742
                        r->off = -1;
 
1743
                        r->sym = s;
 
1744
                        r->add = v;
 
1745
                        v = 0;
 
1746
                }
 
1747
                break;
 
1748
        
 
1749
        case D_INDIR+D_TLS:
 
1750
                if(r == nil) {
 
1751
                        ctxt->diag("need reloc for %D", a);
 
1752
                        sysfatal("bad code");
 
1753
                }
 
1754
                r->type = R_TLS_LE;
 
1755
                r->siz = 4;
 
1756
                r->off = -1; // caller must fill in
 
1757
                r->add = v;
 
1758
                v = 0;
 
1759
                break;
 
1760
        }
 
1761
        return v;
 
1762
}
 
1763
 
 
1764
static void
 
1765
asmand(Link *ctxt, Addr *a, int r)
 
1766
{
 
1767
        int32 v;
 
1768
        int t, scale;
 
1769
        Reloc rel;
 
1770
 
 
1771
        v = a->offset;
 
1772
        t = a->type;
 
1773
        rel.siz = 0;
 
1774
        if(a->index != D_NONE && a->index != D_TLS) {
 
1775
                if(t < D_INDIR || t >= 2*D_INDIR) {
 
1776
                        switch(t) {
 
1777
                        default:
 
1778
                                goto bad;
 
1779
                        case D_STATIC:
 
1780
                        case D_EXTERN:
 
1781
                                t = D_NONE;
 
1782
                                v = vaddr(ctxt, a, &rel);
 
1783
                                break;
 
1784
                        case D_AUTO:
 
1785
                        case D_PARAM:
 
1786
                                t = D_SP;
 
1787
                                break;
 
1788
                        }
 
1789
                } else
 
1790
                        t -= D_INDIR;
 
1791
 
 
1792
                if(t == D_NONE) {
 
1793
                        *ctxt->andptr++ = (0 << 6) | (4 << 0) | (r << 3);
 
1794
                        asmidx(ctxt, a->scale, a->index, t);
 
1795
                        goto putrelv;
 
1796
                }
 
1797
                if(v == 0 && rel.siz == 0 && t != D_BP) {
 
1798
                        *ctxt->andptr++ = (0 << 6) | (4 << 0) | (r << 3);
 
1799
                        asmidx(ctxt, a->scale, a->index, t);
 
1800
                        return;
 
1801
                }
 
1802
                if(v >= -128 && v < 128 && rel.siz == 0) {
 
1803
                        *ctxt->andptr++ = (1 << 6) | (4 << 0) | (r << 3);
 
1804
                        asmidx(ctxt, a->scale, a->index, t);
 
1805
                        *ctxt->andptr++ = v;
 
1806
                        return;
 
1807
                }
 
1808
                *ctxt->andptr++ = (2 << 6) | (4 << 0) | (r << 3);
 
1809
                asmidx(ctxt, a->scale, a->index, t);
 
1810
                goto putrelv;
 
1811
        }
 
1812
        if(t >= D_AL && t <= D_F7 || t >= D_X0 && t <= D_X7) {
 
1813
                if(v)
 
1814
                        goto bad;
 
1815
                *ctxt->andptr++ = (3 << 6) | (reg[t] << 0) | (r << 3);
 
1816
                return;
 
1817
        }
 
1818
        
 
1819
        scale = a->scale;
 
1820
        if(t < D_INDIR || t >= 2*D_INDIR) {
 
1821
                switch(a->type) {
 
1822
                default:
 
1823
                        goto bad;
 
1824
                case D_STATIC:
 
1825
                case D_EXTERN:
 
1826
                        t = D_NONE;
 
1827
                        v = vaddr(ctxt, a, &rel);
 
1828
                        break;
 
1829
                case D_AUTO:
 
1830
                case D_PARAM:
 
1831
                        t = D_SP;
 
1832
                        break;
 
1833
                }
 
1834
                scale = 1;
 
1835
        } else
 
1836
                t -= D_INDIR;
 
1837
        if(t == D_TLS)
 
1838
                v = vaddr(ctxt, a, &rel);
 
1839
 
 
1840
        if(t == D_NONE || (D_CS <= t && t <= D_GS) || t == D_TLS) {
 
1841
                *ctxt->andptr++ = (0 << 6) | (5 << 0) | (r << 3);
 
1842
                goto putrelv;
 
1843
        }
 
1844
        if(t == D_SP) {
 
1845
                if(v == 0 && rel.siz == 0) {
 
1846
                        *ctxt->andptr++ = (0 << 6) | (4 << 0) | (r << 3);
 
1847
                        asmidx(ctxt, scale, D_NONE, t);
 
1848
                        return;
 
1849
                }
 
1850
                if(v >= -128 && v < 128 && rel.siz == 0) {
 
1851
                        *ctxt->andptr++ = (1 << 6) | (4 << 0) | (r << 3);
 
1852
                        asmidx(ctxt, scale, D_NONE, t);
 
1853
                        *ctxt->andptr++ = v;
 
1854
                        return;
 
1855
                }
 
1856
                *ctxt->andptr++ = (2 << 6) | (4 << 0) | (r << 3);
 
1857
                asmidx(ctxt, scale, D_NONE, t);
 
1858
                goto putrelv;
 
1859
        }
 
1860
        if(t >= D_AX && t <= D_DI) {
 
1861
                if(a->index == D_TLS) {
 
1862
                        memset(&rel, 0, sizeof rel);
 
1863
                        rel.type = R_TLS_IE;
 
1864
                        rel.siz = 4;
 
1865
                        rel.sym = nil;
 
1866
                        rel.add = v;
 
1867
                        v = 0;
 
1868
                }
 
1869
                if(v == 0 && rel.siz == 0 && t != D_BP) {
 
1870
                        *ctxt->andptr++ = (0 << 6) | (reg[t] << 0) | (r << 3);
 
1871
                        return;
 
1872
                }
 
1873
                if(v >= -128 && v < 128 && rel.siz == 0)  {
 
1874
                        ctxt->andptr[0] = (1 << 6) | (reg[t] << 0) | (r << 3);
 
1875
                        ctxt->andptr[1] = v;
 
1876
                        ctxt->andptr += 2;
 
1877
                        return;
 
1878
                }
 
1879
                *ctxt->andptr++ = (2 << 6) | (reg[t] << 0) | (r << 3);
 
1880
                goto putrelv;
 
1881
        }
 
1882
        goto bad;
 
1883
 
 
1884
putrelv:
 
1885
        if(rel.siz != 0) {
 
1886
                Reloc *r;
 
1887
                
 
1888
                if(rel.siz != 4) {
 
1889
                        ctxt->diag("bad rel");
 
1890
                        goto bad;
 
1891
                }
 
1892
                r = addrel(ctxt->cursym);
 
1893
                *r = rel;
 
1894
                r->off = ctxt->curp->pc + ctxt->andptr - ctxt->and;
 
1895
        }
 
1896
 
 
1897
        put4(ctxt, v);
 
1898
        return;
 
1899
 
 
1900
bad:
 
1901
        ctxt->diag("asmand: bad address %D", a);
 
1902
        return;
 
1903
}
 
1904
 
 
1905
#define E       0xff
 
1906
static uchar    ymovtab[] =
 
1907
{
 
1908
/* push */
 
1909
        APUSHL, Ycs,    Ynone,  0,      0x0e,E,0,0,
 
1910
        APUSHL, Yss,    Ynone,  0,      0x16,E,0,0,
 
1911
        APUSHL, Yds,    Ynone,  0,      0x1e,E,0,0,
 
1912
        APUSHL, Yes,    Ynone,  0,      0x06,E,0,0,
 
1913
        APUSHL, Yfs,    Ynone,  0,      0x0f,0xa0,E,0,
 
1914
        APUSHL, Ygs,    Ynone,  0,      0x0f,0xa8,E,0,
 
1915
 
 
1916
        APUSHW, Ycs,    Ynone,  0,      Pe,0x0e,E,0,
 
1917
        APUSHW, Yss,    Ynone,  0,      Pe,0x16,E,0,
 
1918
        APUSHW, Yds,    Ynone,  0,      Pe,0x1e,E,0,
 
1919
        APUSHW, Yes,    Ynone,  0,      Pe,0x06,E,0,
 
1920
        APUSHW, Yfs,    Ynone,  0,      Pe,0x0f,0xa0,E,
 
1921
        APUSHW, Ygs,    Ynone,  0,      Pe,0x0f,0xa8,E,
 
1922
 
 
1923
/* pop */
 
1924
        APOPL,  Ynone,  Yds,    0,      0x1f,E,0,0,
 
1925
        APOPL,  Ynone,  Yes,    0,      0x07,E,0,0,
 
1926
        APOPL,  Ynone,  Yss,    0,      0x17,E,0,0,
 
1927
        APOPL,  Ynone,  Yfs,    0,      0x0f,0xa1,E,0,
 
1928
        APOPL,  Ynone,  Ygs,    0,      0x0f,0xa9,E,0,
 
1929
 
 
1930
        APOPW,  Ynone,  Yds,    0,      Pe,0x1f,E,0,
 
1931
        APOPW,  Ynone,  Yes,    0,      Pe,0x07,E,0,
 
1932
        APOPW,  Ynone,  Yss,    0,      Pe,0x17,E,0,
 
1933
        APOPW,  Ynone,  Yfs,    0,      Pe,0x0f,0xa1,E,
 
1934
        APOPW,  Ynone,  Ygs,    0,      Pe,0x0f,0xa9,E,
 
1935
 
 
1936
/* mov seg */
 
1937
        AMOVW,  Yes,    Yml,    1,      0x8c,0,0,0,
 
1938
        AMOVW,  Ycs,    Yml,    1,      0x8c,1,0,0,
 
1939
        AMOVW,  Yss,    Yml,    1,      0x8c,2,0,0,
 
1940
        AMOVW,  Yds,    Yml,    1,      0x8c,3,0,0,
 
1941
        AMOVW,  Yfs,    Yml,    1,      0x8c,4,0,0,
 
1942
        AMOVW,  Ygs,    Yml,    1,      0x8c,5,0,0,
 
1943
 
 
1944
        AMOVW,  Yml,    Yes,    2,      0x8e,0,0,0,
 
1945
        AMOVW,  Yml,    Ycs,    2,      0x8e,1,0,0,
 
1946
        AMOVW,  Yml,    Yss,    2,      0x8e,2,0,0,
 
1947
        AMOVW,  Yml,    Yds,    2,      0x8e,3,0,0,
 
1948
        AMOVW,  Yml,    Yfs,    2,      0x8e,4,0,0,
 
1949
        AMOVW,  Yml,    Ygs,    2,      0x8e,5,0,0,
 
1950
 
 
1951
/* mov cr */
 
1952
        AMOVL,  Ycr0,   Yml,    3,      0x0f,0x20,0,0,
 
1953
        AMOVL,  Ycr2,   Yml,    3,      0x0f,0x20,2,0,
 
1954
        AMOVL,  Ycr3,   Yml,    3,      0x0f,0x20,3,0,
 
1955
        AMOVL,  Ycr4,   Yml,    3,      0x0f,0x20,4,0,
 
1956
 
 
1957
        AMOVL,  Yml,    Ycr0,   4,      0x0f,0x22,0,0,
 
1958
        AMOVL,  Yml,    Ycr2,   4,      0x0f,0x22,2,0,
 
1959
        AMOVL,  Yml,    Ycr3,   4,      0x0f,0x22,3,0,
 
1960
        AMOVL,  Yml,    Ycr4,   4,      0x0f,0x22,4,0,
 
1961
 
 
1962
/* mov dr */
 
1963
        AMOVL,  Ydr0,   Yml,    3,      0x0f,0x21,0,0,
 
1964
        AMOVL,  Ydr6,   Yml,    3,      0x0f,0x21,6,0,
 
1965
        AMOVL,  Ydr7,   Yml,    3,      0x0f,0x21,7,0,
 
1966
 
 
1967
        AMOVL,  Yml,    Ydr0,   4,      0x0f,0x23,0,0,
 
1968
        AMOVL,  Yml,    Ydr6,   4,      0x0f,0x23,6,0,
 
1969
        AMOVL,  Yml,    Ydr7,   4,      0x0f,0x23,7,0,
 
1970
 
 
1971
/* mov tr */
 
1972
        AMOVL,  Ytr6,   Yml,    3,      0x0f,0x24,6,0,
 
1973
        AMOVL,  Ytr7,   Yml,    3,      0x0f,0x24,7,0,
 
1974
 
 
1975
        AMOVL,  Yml,    Ytr6,   4,      0x0f,0x26,6,E,
 
1976
        AMOVL,  Yml,    Ytr7,   4,      0x0f,0x26,7,E,
 
1977
 
 
1978
/* lgdt, sgdt, lidt, sidt */
 
1979
        AMOVL,  Ym,     Ygdtr,  4,      0x0f,0x01,2,0,
 
1980
        AMOVL,  Ygdtr,  Ym,     3,      0x0f,0x01,0,0,
 
1981
        AMOVL,  Ym,     Yidtr,  4,      0x0f,0x01,3,0,
 
1982
        AMOVL,  Yidtr,  Ym,     3,      0x0f,0x01,1,0,
 
1983
 
 
1984
/* lldt, sldt */
 
1985
        AMOVW,  Yml,    Yldtr,  4,      0x0f,0x00,2,0,
 
1986
        AMOVW,  Yldtr,  Yml,    3,      0x0f,0x00,0,0,
 
1987
 
 
1988
/* lmsw, smsw */
 
1989
        AMOVW,  Yml,    Ymsw,   4,      0x0f,0x01,6,0,
 
1990
        AMOVW,  Ymsw,   Yml,    3,      0x0f,0x01,4,0,
 
1991
 
 
1992
/* ltr, str */
 
1993
        AMOVW,  Yml,    Ytask,  4,      0x0f,0x00,3,0,
 
1994
        AMOVW,  Ytask,  Yml,    3,      0x0f,0x00,1,0,
 
1995
 
 
1996
/* load full pointer */
 
1997
        AMOVL,  Yml,    Ycol,   5,      0,0,0,0,
 
1998
        AMOVW,  Yml,    Ycol,   5,      Pe,0,0,0,
 
1999
 
 
2000
/* double shift */
 
2001
        ASHLL,  Ycol,   Yml,    6,      0xa4,0xa5,0,0,
 
2002
        ASHRL,  Ycol,   Yml,    6,      0xac,0xad,0,0,
 
2003
 
 
2004
/* extra imul */
 
2005
        AIMULW, Yml,    Yrl,    7,      Pq,0xaf,0,0,
 
2006
        AIMULL, Yml,    Yrl,    7,      Pm,0xaf,0,0,
 
2007
 
 
2008
/* load TLS base pointer */
 
2009
        AMOVL,  Ytls,   Yrl,    8,      0,0,0,0,
 
2010
 
 
2011
        0
 
2012
};
 
2013
 
 
2014
// byteswapreg returns a byte-addressable register (AX, BX, CX, DX)
 
2015
// which is not referenced in a->type.
 
2016
// If a is empty, it returns BX to account for MULB-like instructions
 
2017
// that might use DX and AX.
 
2018
static int
 
2019
byteswapreg(Link *ctxt, Addr *a)
 
2020
{
 
2021
        int cana, canb, canc, cand;
 
2022
 
 
2023
        cana = canb = canc = cand = 1;
 
2024
 
 
2025
        switch(a->type) {
 
2026
        case D_NONE:
 
2027
                cana = cand = 0;
 
2028
                break;
 
2029
        case D_AX:
 
2030
        case D_AL:
 
2031
        case D_AH:
 
2032
        case D_INDIR+D_AX:
 
2033
                cana = 0;
 
2034
                break;
 
2035
        case D_BX:
 
2036
        case D_BL:
 
2037
        case D_BH:
 
2038
        case D_INDIR+D_BX:
 
2039
                canb = 0;
 
2040
                break;
 
2041
        case D_CX:
 
2042
        case D_CL:
 
2043
        case D_CH:
 
2044
        case D_INDIR+D_CX:
 
2045
                canc = 0;
 
2046
                break;
 
2047
        case D_DX:
 
2048
        case D_DL:
 
2049
        case D_DH:
 
2050
        case D_INDIR+D_DX:
 
2051
                cand = 0;
 
2052
                break;
 
2053
        }
 
2054
        switch(a->index) {
 
2055
        case D_AX:
 
2056
                cana = 0;
 
2057
                break;
 
2058
        case D_BX:
 
2059
                canb = 0;
 
2060
                break;
 
2061
        case D_CX:
 
2062
                canc = 0;
 
2063
                break;
 
2064
        case D_DX:
 
2065
                cand = 0;
 
2066
                break;
 
2067
        }
 
2068
        if(cana)
 
2069
                return D_AX;
 
2070
        if(canb)
 
2071
                return D_BX;
 
2072
        if(canc)
 
2073
                return D_CX;
 
2074
        if(cand)
 
2075
                return D_DX;
 
2076
 
 
2077
        ctxt->diag("impossible byte register");
 
2078
        sysfatal("bad code");
 
2079
        return 0;
 
2080
}
 
2081
 
 
2082
static void
 
2083
subreg(Prog *p, int from, int to)
 
2084
{
 
2085
 
 
2086
        if(0 /* debug['Q'] */)
 
2087
                print("\n%P     s/%R/%R/\n", p, from, to);
 
2088
 
 
2089
        if(p->from.type == from) {
 
2090
                p->from.type = to;
 
2091
                p->ft = 0;
 
2092
        }
 
2093
        if(p->to.type == from) {
 
2094
                p->to.type = to;
 
2095
                p->tt = 0;
 
2096
        }
 
2097
 
 
2098
        if(p->from.index == from) {
 
2099
                p->from.index = to;
 
2100
                p->ft = 0;
 
2101
        }
 
2102
        if(p->to.index == from) {
 
2103
                p->to.index = to;
 
2104
                p->tt = 0;
 
2105
        }
 
2106
 
 
2107
        from += D_INDIR;
 
2108
        if(p->from.type == from) {
 
2109
                p->from.type = to+D_INDIR;
 
2110
                p->ft = 0;
 
2111
        }
 
2112
        if(p->to.type == from) {
 
2113
                p->to.type = to+D_INDIR;
 
2114
                p->tt = 0;
 
2115
        }
 
2116
 
 
2117
        if(0 /* debug['Q'] */)
 
2118
                print("%P\n", p);
 
2119
}
 
2120
 
 
2121
static int
 
2122
mediaop(Link *ctxt, Optab *o, int op, int osize, int z)
 
2123
{
 
2124
        switch(op){
 
2125
        case Pm:
 
2126
        case Pe:
 
2127
        case Pf2:
 
2128
        case Pf3:
 
2129
                if(osize != 1){
 
2130
                        if(op != Pm)
 
2131
                                *ctxt->andptr++ = op;
 
2132
                        *ctxt->andptr++ = Pm;
 
2133
                        op = o->op[++z];
 
2134
                        break;
 
2135
                }
 
2136
        default:
 
2137
                if(ctxt->andptr == ctxt->and || ctxt->andptr[-1] != Pm)
 
2138
                        *ctxt->andptr++ = Pm;
 
2139
                break;
 
2140
        }
 
2141
        *ctxt->andptr++ = op;
 
2142
        return z;
 
2143
}
 
2144
 
 
2145
static void
 
2146
doasm(Link *ctxt, Prog *p)
 
2147
{
 
2148
        Optab *o;
 
2149
        Prog *q, pp;
 
2150
        uchar *t;
 
2151
        int z, op, ft, tt, breg;
 
2152
        int32 v, pre;
 
2153
        Reloc rel, *r;
 
2154
        Addr *a;
 
2155
        
 
2156
        ctxt->curp = p; // TODO
 
2157
 
 
2158
        pre = prefixof(ctxt, &p->from);
 
2159
        if(pre)
 
2160
                *ctxt->andptr++ = pre;
 
2161
        pre = prefixof(ctxt, &p->to);
 
2162
        if(pre)
 
2163
                *ctxt->andptr++ = pre;
 
2164
 
 
2165
        if(p->ft == 0)
 
2166
                p->ft = oclass(&p->from);
 
2167
        if(p->tt == 0)
 
2168
                p->tt = oclass(&p->to);
 
2169
 
 
2170
        ft = p->ft * Ymax;
 
2171
        tt = p->tt * Ymax;
 
2172
        o = &optab[p->as];
 
2173
        t = o->ytab;
 
2174
        if(t == 0) {
 
2175
                ctxt->diag("asmins: noproto %P", p);
 
2176
                return;
 
2177
        }
 
2178
        for(z=0; *t; z+=t[3],t+=4)
 
2179
                if(ycover[ft+t[0]])
 
2180
                if(ycover[tt+t[1]])
 
2181
                        goto found;
 
2182
        goto domov;
 
2183
 
 
2184
found:
 
2185
        switch(o->prefix) {
 
2186
        case Pq:        /* 16 bit escape and opcode escape */
 
2187
                *ctxt->andptr++ = Pe;
 
2188
                *ctxt->andptr++ = Pm;
 
2189
                break;
 
2190
 
 
2191
        case Pf2:       /* xmm opcode escape */
 
2192
        case Pf3:
 
2193
                *ctxt->andptr++ = o->prefix;
 
2194
                *ctxt->andptr++ = Pm;
 
2195
                break;
 
2196
 
 
2197
        case Pm:        /* opcode escape */
 
2198
                *ctxt->andptr++ = Pm;
 
2199
                break;
 
2200
 
 
2201
        case Pe:        /* 16 bit escape */
 
2202
                *ctxt->andptr++ = Pe;
 
2203
                break;
 
2204
 
 
2205
        case Pb:        /* botch */
 
2206
                break;
 
2207
        }
 
2208
 
 
2209
        op = o->op[z];
 
2210
        switch(t[2]) {
 
2211
        default:
 
2212
                ctxt->diag("asmins: unknown z %d %P", t[2], p);
 
2213
                return;
 
2214
 
 
2215
        case Zpseudo:
 
2216
                break;
 
2217
 
 
2218
        case Zlit:
 
2219
                for(; op = o->op[z]; z++)
 
2220
                        *ctxt->andptr++ = op;
 
2221
                break;
 
2222
 
 
2223
        case Zlitm_r:
 
2224
                for(; op = o->op[z]; z++)
 
2225
                        *ctxt->andptr++ = op;
 
2226
                asmand(ctxt, &p->from, reg[p->to.type]);
 
2227
                break;
 
2228
 
 
2229
        case Zm_r:
 
2230
                *ctxt->andptr++ = op;
 
2231
                asmand(ctxt, &p->from, reg[p->to.type]);
 
2232
                break;
 
2233
 
 
2234
        case Zm2_r:
 
2235
                *ctxt->andptr++ = op;
 
2236
                *ctxt->andptr++ = o->op[z+1];
 
2237
                asmand(ctxt, &p->from, reg[p->to.type]);
 
2238
                break;
 
2239
 
 
2240
        case Zm_r_xm:
 
2241
                mediaop(ctxt, o, op, t[3], z);
 
2242
                asmand(ctxt, &p->from, reg[p->to.type]);
 
2243
                break;
 
2244
 
 
2245
        case Zm_r_i_xm:
 
2246
                mediaop(ctxt, o, op, t[3], z);
 
2247
                asmand(ctxt, &p->from, reg[p->to.type]);
 
2248
                *ctxt->andptr++ = p->to.offset;
 
2249
                break;
 
2250
 
 
2251
        case Zibm_r:
 
2252
                while ((op = o->op[z++]) != 0)
 
2253
                        *ctxt->andptr++ = op;
 
2254
                asmand(ctxt, &p->from, reg[p->to.type]);
 
2255
                *ctxt->andptr++ = p->to.offset;
 
2256
                break;
 
2257
 
 
2258
        case Zaut_r:
 
2259
                *ctxt->andptr++ = 0x8d; /* leal */
 
2260
                if(p->from.type != D_ADDR)
 
2261
                        ctxt->diag("asmins: Zaut sb type ADDR");
 
2262
                p->from.type = p->from.index;
 
2263
                p->from.index = D_NONE;
 
2264
                p->ft = 0;
 
2265
                asmand(ctxt, &p->from, reg[p->to.type]);
 
2266
                p->from.index = p->from.type;
 
2267
                p->from.type = D_ADDR;
 
2268
                p->ft = 0;
 
2269
                break;
 
2270
 
 
2271
        case Zm_o:
 
2272
                *ctxt->andptr++ = op;
 
2273
                asmand(ctxt, &p->from, o->op[z+1]);
 
2274
                break;
 
2275
 
 
2276
        case Zr_m:
 
2277
                *ctxt->andptr++ = op;
 
2278
                asmand(ctxt, &p->to, reg[p->from.type]);
 
2279
                break;
 
2280
 
 
2281
        case Zr_m_xm:
 
2282
                mediaop(ctxt, o, op, t[3], z);
 
2283
                asmand(ctxt, &p->to, reg[p->from.type]);
 
2284
                break;
 
2285
 
 
2286
        case Zr_m_i_xm:
 
2287
                mediaop(ctxt, o, op, t[3], z);
 
2288
                asmand(ctxt, &p->to, reg[p->from.type]);
 
2289
                *ctxt->andptr++ = p->from.offset;
 
2290
                break;
 
2291
 
 
2292
        case Zo_m:
 
2293
        case_Zo_m:
 
2294
                *ctxt->andptr++ = op;
 
2295
                asmand(ctxt, &p->to, o->op[z+1]);
 
2296
                break;
 
2297
 
 
2298
        case Zm_ibo:
 
2299
                *ctxt->andptr++ = op;
 
2300
                asmand(ctxt, &p->from, o->op[z+1]);
 
2301
                *ctxt->andptr++ = vaddr(ctxt, &p->to, nil);
 
2302
                break;
 
2303
 
 
2304
        case Zibo_m:
 
2305
                *ctxt->andptr++ = op;
 
2306
                asmand(ctxt, &p->to, o->op[z+1]);
 
2307
                *ctxt->andptr++ = vaddr(ctxt, &p->from, nil);
 
2308
                break;
 
2309
 
 
2310
        case Z_ib:
 
2311
        case Zib_:
 
2312
                if(t[2] == Zib_)
 
2313
                        a = &p->from;
 
2314
                else
 
2315
                        a = &p->to;
 
2316
                v = vaddr(ctxt, a, nil);
 
2317
                *ctxt->andptr++ = op;
 
2318
                *ctxt->andptr++ = v;
 
2319
                break;
 
2320
 
 
2321
        case Zib_rp:
 
2322
                *ctxt->andptr++ = op + reg[p->to.type];
 
2323
                *ctxt->andptr++ = vaddr(ctxt, &p->from, nil);
 
2324
                break;
 
2325
 
 
2326
        case Zil_rp:
 
2327
                *ctxt->andptr++ = op + reg[p->to.type];
 
2328
                if(o->prefix == Pe) {
 
2329
                        v = vaddr(ctxt, &p->from, nil);
 
2330
                        *ctxt->andptr++ = v;
 
2331
                        *ctxt->andptr++ = v>>8;
 
2332
                }
 
2333
                else
 
2334
                        relput4(ctxt, p, &p->from);
 
2335
                break;
 
2336
 
 
2337
        case Zib_rr:
 
2338
                *ctxt->andptr++ = op;
 
2339
                asmand(ctxt, &p->to, reg[p->to.type]);
 
2340
                *ctxt->andptr++ = vaddr(ctxt, &p->from, nil);
 
2341
                break;
 
2342
 
 
2343
        case Z_il:
 
2344
        case Zil_:
 
2345
                if(t[2] == Zil_)
 
2346
                        a = &p->from;
 
2347
                else
 
2348
                        a = &p->to;
 
2349
                *ctxt->andptr++ = op;
 
2350
                if(o->prefix == Pe) {
 
2351
                        v = vaddr(ctxt, a, nil);
 
2352
                        *ctxt->andptr++ = v;
 
2353
                        *ctxt->andptr++ = v>>8;
 
2354
                }
 
2355
                else
 
2356
                        relput4(ctxt, p, a);
 
2357
                break;
 
2358
 
 
2359
        case Zm_ilo:
 
2360
        case Zilo_m:
 
2361
                *ctxt->andptr++ = op;
 
2362
                if(t[2] == Zilo_m) {
 
2363
                        a = &p->from;
 
2364
                        asmand(ctxt, &p->to, o->op[z+1]);
 
2365
                } else {
 
2366
                        a = &p->to;
 
2367
                        asmand(ctxt, &p->from, o->op[z+1]);
 
2368
                }
 
2369
                if(o->prefix == Pe) {
 
2370
                        v = vaddr(ctxt, a, nil);
 
2371
                        *ctxt->andptr++ = v;
 
2372
                        *ctxt->andptr++ = v>>8;
 
2373
                }
 
2374
                else
 
2375
                        relput4(ctxt, p, a);
 
2376
                break;
 
2377
 
 
2378
        case Zil_rr:
 
2379
                *ctxt->andptr++ = op;
 
2380
                asmand(ctxt, &p->to, reg[p->to.type]);
 
2381
                if(o->prefix == Pe) {
 
2382
                        v = vaddr(ctxt, &p->from, nil);
 
2383
                        *ctxt->andptr++ = v;
 
2384
                        *ctxt->andptr++ = v>>8;
 
2385
                }
 
2386
                else
 
2387
                        relput4(ctxt, p, &p->from);
 
2388
                break;
 
2389
 
 
2390
        case Z_rp:
 
2391
                *ctxt->andptr++ = op + reg[p->to.type];
 
2392
                break;
 
2393
 
 
2394
        case Zrp_:
 
2395
                *ctxt->andptr++ = op + reg[p->from.type];
 
2396
                break;
 
2397
 
 
2398
        case Zclr:
 
2399
                *ctxt->andptr++ = op;
 
2400
                asmand(ctxt, &p->to, reg[p->to.type]);
 
2401
                break;
 
2402
        
 
2403
        case Zcall:
 
2404
                if(p->to.sym == nil) {
 
2405
                        ctxt->diag("call without target");
 
2406
                        sysfatal("bad code");
 
2407
                }
 
2408
                *ctxt->andptr++ = op;
 
2409
                r = addrel(ctxt->cursym);
 
2410
                r->off = p->pc + ctxt->andptr - ctxt->and;
 
2411
                r->type = R_CALL;
 
2412
                r->siz = 4;
 
2413
                r->sym = p->to.sym;
 
2414
                r->add = p->to.offset;
 
2415
                put4(ctxt, 0);
 
2416
                break;
 
2417
 
 
2418
        case Zbr:
 
2419
        case Zjmp:
 
2420
        case Zloop:
 
2421
                if(p->to.sym != nil) {
 
2422
                        if(t[2] != Zjmp) {
 
2423
                                ctxt->diag("branch to ATEXT");
 
2424
                                sysfatal("bad code");
 
2425
                        }
 
2426
                        *ctxt->andptr++ = o->op[z+1];
 
2427
                        r = addrel(ctxt->cursym);
 
2428
                        r->off = p->pc + ctxt->andptr - ctxt->and;
 
2429
                        r->sym = p->to.sym;
 
2430
                        r->type = R_PCREL;
 
2431
                        r->siz = 4;
 
2432
                        put4(ctxt, 0);
 
2433
                        break;
 
2434
                }
 
2435
 
 
2436
                // Assumes q is in this function.
 
2437
                // Fill in backward jump now.
 
2438
                q = p->pcond;
 
2439
                if(q == nil) {
 
2440
                        ctxt->diag("jmp/branch/loop without target");
 
2441
                        sysfatal("bad code");
 
2442
                }
 
2443
                if(p->back & 1) {
 
2444
                        v = q->pc - (p->pc + 2);
 
2445
                        if(v >= -128) {
 
2446
                                if(p->as == AJCXZW)
 
2447
                                        *ctxt->andptr++ = 0x67;
 
2448
                                *ctxt->andptr++ = op;
 
2449
                                *ctxt->andptr++ = v;
 
2450
                        } else if(t[2] == Zloop) {
 
2451
                                ctxt->diag("loop too far: %P", p);
 
2452
                        } else {
 
2453
                                v -= 5-2;
 
2454
                                if(t[2] == Zbr) {
 
2455
                                        *ctxt->andptr++ = 0x0f;
 
2456
                                        v--;
 
2457
                                }
 
2458
                                *ctxt->andptr++ = o->op[z+1];
 
2459
                                *ctxt->andptr++ = v;
 
2460
                                *ctxt->andptr++ = v>>8;
 
2461
                                *ctxt->andptr++ = v>>16;
 
2462
                                *ctxt->andptr++ = v>>24;
 
2463
                        }
 
2464
                        break;
 
2465
                }
 
2466
 
 
2467
                // Annotate target; will fill in later.
 
2468
                p->forwd = q->comefrom;
 
2469
                q->comefrom = p;
 
2470
                if(p->back & 2) { // short
 
2471
                        if(p->as == AJCXZW)
 
2472
                                *ctxt->andptr++ = 0x67;
 
2473
                        *ctxt->andptr++ = op;
 
2474
                        *ctxt->andptr++ = 0;
 
2475
                } else if(t[2] == Zloop) {
 
2476
                        ctxt->diag("loop too far: %P", p);
 
2477
                } else {
 
2478
                        if(t[2] == Zbr)
 
2479
                                *ctxt->andptr++ = 0x0f;
 
2480
                        *ctxt->andptr++ = o->op[z+1];
 
2481
                        *ctxt->andptr++ = 0;
 
2482
                        *ctxt->andptr++ = 0;
 
2483
                        *ctxt->andptr++ = 0;
 
2484
                        *ctxt->andptr++ = 0;
 
2485
                }
 
2486
                break;
 
2487
 
 
2488
        case Zcallcon:
 
2489
        case Zjmpcon:
 
2490
                if(t[2] == Zcallcon)
 
2491
                        *ctxt->andptr++ = op;
 
2492
                else
 
2493
                        *ctxt->andptr++ = o->op[z+1];
 
2494
                r = addrel(ctxt->cursym);
 
2495
                r->off = p->pc + ctxt->andptr - ctxt->and;
 
2496
                r->type = R_PCREL;
 
2497
                r->siz = 4;
 
2498
                r->add = p->to.offset;
 
2499
                put4(ctxt, 0);
 
2500
                break;
 
2501
        
 
2502
        case Zcallind:
 
2503
                *ctxt->andptr++ = op;
 
2504
                *ctxt->andptr++ = o->op[z+1];
 
2505
                r = addrel(ctxt->cursym);
 
2506
                r->off = p->pc + ctxt->andptr - ctxt->and;
 
2507
                r->type = R_ADDR;
 
2508
                r->siz = 4;
 
2509
                r->add = p->to.offset;
 
2510
                r->sym = p->to.sym;
 
2511
                put4(ctxt, 0);
 
2512
                break;
 
2513
 
 
2514
        case Zcallindreg:
 
2515
                r = addrel(ctxt->cursym);
 
2516
                r->off = p->pc;
 
2517
                r->type = R_CALLIND;
 
2518
                r->siz = 0;
 
2519
                goto case_Zo_m;
 
2520
 
 
2521
        case Zbyte:
 
2522
                v = vaddr(ctxt, &p->from, &rel);
 
2523
                if(rel.siz != 0) {
 
2524
                        rel.siz = op;
 
2525
                        r = addrel(ctxt->cursym);
 
2526
                        *r = rel;
 
2527
                        r->off = p->pc + ctxt->andptr - ctxt->and;
 
2528
                }
 
2529
                *ctxt->andptr++ = v;
 
2530
                if(op > 1) {
 
2531
                        *ctxt->andptr++ = v>>8;
 
2532
                        if(op > 2) {
 
2533
                                *ctxt->andptr++ = v>>16;
 
2534
                                *ctxt->andptr++ = v>>24;
 
2535
                        }
 
2536
                }
 
2537
                break;
 
2538
 
 
2539
        case Zmov:
 
2540
                goto domov;
 
2541
        }
 
2542
        return;
 
2543
 
 
2544
domov:
 
2545
        for(t=ymovtab; *t; t+=8)
 
2546
                if(p->as == t[0])
 
2547
                if(ycover[ft+t[1]])
 
2548
                if(ycover[tt+t[2]])
 
2549
                        goto mfound;
 
2550
bad:
 
2551
        /*
 
2552
         * here, the assembly has failed.
 
2553
         * if its a byte instruction that has
 
2554
         * unaddressable registers, try to
 
2555
         * exchange registers and reissue the
 
2556
         * instruction with the operands renamed.
 
2557
         */
 
2558
        pp = *p;
 
2559
        z = p->from.type;
 
2560
        if(z >= D_BP && z <= D_DI) {
 
2561
                if((breg = byteswapreg(ctxt, &p->to)) != D_AX) {
 
2562
                        *ctxt->andptr++ = 0x87;                 /* xchg lhs,bx */
 
2563
                        asmand(ctxt, &p->from, reg[breg]);
 
2564
                        subreg(&pp, z, breg);
 
2565
                        doasm(ctxt, &pp);
 
2566
                        *ctxt->andptr++ = 0x87;                 /* xchg lhs,bx */
 
2567
                        asmand(ctxt, &p->from, reg[breg]);
 
2568
                } else {
 
2569
                        *ctxt->andptr++ = 0x90 + reg[z];                /* xchg lsh,ax */
 
2570
                        subreg(&pp, z, D_AX);
 
2571
                        doasm(ctxt, &pp);
 
2572
                        *ctxt->andptr++ = 0x90 + reg[z];                /* xchg lsh,ax */
 
2573
                }
 
2574
                return;
 
2575
        }
 
2576
        z = p->to.type;
 
2577
        if(z >= D_BP && z <= D_DI) {
 
2578
                if((breg = byteswapreg(ctxt, &p->from)) != D_AX) {
 
2579
                        *ctxt->andptr++ = 0x87;                 /* xchg rhs,bx */
 
2580
                        asmand(ctxt, &p->to, reg[breg]);
 
2581
                        subreg(&pp, z, breg);
 
2582
                        doasm(ctxt, &pp);
 
2583
                        *ctxt->andptr++ = 0x87;                 /* xchg rhs,bx */
 
2584
                        asmand(ctxt, &p->to, reg[breg]);
 
2585
                } else {
 
2586
                        *ctxt->andptr++ = 0x90 + reg[z];                /* xchg rsh,ax */
 
2587
                        subreg(&pp, z, D_AX);
 
2588
                        doasm(ctxt, &pp);
 
2589
                        *ctxt->andptr++ = 0x90 + reg[z];                /* xchg rsh,ax */
 
2590
                }
 
2591
                return;
 
2592
        }
 
2593
        ctxt->diag("doasm: notfound t2=%ux from=%ux to=%ux %P", t[2], p->from.type, p->to.type, p);
 
2594
        return;
 
2595
 
 
2596
mfound:
 
2597
        switch(t[3]) {
 
2598
        default:
 
2599
                ctxt->diag("asmins: unknown mov %d %P", t[3], p);
 
2600
                break;
 
2601
 
 
2602
        case 0: /* lit */
 
2603
                for(z=4; t[z]!=E; z++)
 
2604
                        *ctxt->andptr++ = t[z];
 
2605
                break;
 
2606
 
 
2607
        case 1: /* r,m */
 
2608
                *ctxt->andptr++ = t[4];
 
2609
                asmand(ctxt, &p->to, t[5]);
 
2610
                break;
 
2611
 
 
2612
        case 2: /* m,r */
 
2613
                *ctxt->andptr++ = t[4];
 
2614
                asmand(ctxt, &p->from, t[5]);
 
2615
                break;
 
2616
 
 
2617
        case 3: /* r,m - 2op */
 
2618
                *ctxt->andptr++ = t[4];
 
2619
                *ctxt->andptr++ = t[5];
 
2620
                asmand(ctxt, &p->to, t[6]);
 
2621
                break;
 
2622
 
 
2623
        case 4: /* m,r - 2op */
 
2624
                *ctxt->andptr++ = t[4];
 
2625
                *ctxt->andptr++ = t[5];
 
2626
                asmand(ctxt, &p->from, t[6]);
 
2627
                break;
 
2628
 
 
2629
        case 5: /* load full pointer, trash heap */
 
2630
                if(t[4])
 
2631
                        *ctxt->andptr++ = t[4];
 
2632
                switch(p->to.index) {
 
2633
                default:
 
2634
                        goto bad;
 
2635
                case D_DS:
 
2636
                        *ctxt->andptr++ = 0xc5;
 
2637
                        break;
 
2638
                case D_SS:
 
2639
                        *ctxt->andptr++ = 0x0f;
 
2640
                        *ctxt->andptr++ = 0xb2;
 
2641
                        break;
 
2642
                case D_ES:
 
2643
                        *ctxt->andptr++ = 0xc4;
 
2644
                        break;
 
2645
                case D_FS:
 
2646
                        *ctxt->andptr++ = 0x0f;
 
2647
                        *ctxt->andptr++ = 0xb4;
 
2648
                        break;
 
2649
                case D_GS:
 
2650
                        *ctxt->andptr++ = 0x0f;
 
2651
                        *ctxt->andptr++ = 0xb5;
 
2652
                        break;
 
2653
                }
 
2654
                asmand(ctxt, &p->from, reg[p->to.type]);
 
2655
                break;
 
2656
 
 
2657
        case 6: /* double shift */
 
2658
                z = p->from.type;
 
2659
                switch(z) {
 
2660
                default:
 
2661
                        goto bad;
 
2662
                case D_CONST:
 
2663
                        *ctxt->andptr++ = 0x0f;
 
2664
                        *ctxt->andptr++ = t[4];
 
2665
                        asmand(ctxt, &p->to, reg[p->from.index]);
 
2666
                        *ctxt->andptr++ = p->from.offset;
 
2667
                        break;
 
2668
                case D_CL:
 
2669
                case D_CX:
 
2670
                        *ctxt->andptr++ = 0x0f;
 
2671
                        *ctxt->andptr++ = t[5];
 
2672
                        asmand(ctxt, &p->to, reg[p->from.index]);
 
2673
                        break;
 
2674
                }
 
2675
                break;
 
2676
 
 
2677
        case 7: /* imul rm,r */
 
2678
                if(t[4] == Pq) {
 
2679
                        *ctxt->andptr++ = Pe;
 
2680
                        *ctxt->andptr++ = Pm;
 
2681
                } else
 
2682
                        *ctxt->andptr++ = t[4];
 
2683
                *ctxt->andptr++ = t[5];
 
2684
                asmand(ctxt, &p->from, reg[p->to.type]);
 
2685
                break;
 
2686
        
 
2687
        case 8: /* mov tls, r */
 
2688
                // NOTE: The systems listed here are the ones that use the "TLS initial exec" model,
 
2689
                // where you load the TLS base register into a register and then index off that
 
2690
                // register to access the actual TLS variables. Systems that allow direct TLS access
 
2691
                // are handled in prefixof above and should not be listed here.
 
2692
                switch(ctxt->headtype) {
 
2693
                default:
 
2694
                        sysfatal("unknown TLS base location for %s", headstr(ctxt->headtype));
 
2695
 
 
2696
                case Hlinux:
 
2697
                case Hnacl:
 
2698
                        // ELF TLS base is 0(GS).
 
2699
                        pp.from = p->from;
 
2700
                        pp.from.type = D_INDIR+D_GS;
 
2701
                        pp.from.offset = 0;
 
2702
                        pp.from.index = D_NONE;
 
2703
                        pp.from.scale = 0;
 
2704
                        *ctxt->andptr++ = 0x65; // GS
 
2705
                        *ctxt->andptr++ = 0x8B;
 
2706
                        asmand(ctxt, &pp.from, reg[p->to.type]);
 
2707
                        break;
 
2708
                
 
2709
                case Hplan9:
 
2710
                        if(ctxt->plan9tos == nil)
 
2711
                                ctxt->plan9tos = linklookup(ctxt, "_tos", 0);
 
2712
                        memset(&pp.from, 0, sizeof pp.from);
 
2713
                        pp.from.type = D_EXTERN;
 
2714
                        pp.from.sym = ctxt->plan9tos;
 
2715
                        pp.from.offset = 0;
 
2716
                        pp.from.index = D_NONE;
 
2717
                        *ctxt->andptr++ = 0x8B;
 
2718
                        asmand(ctxt, &pp.from, reg[p->to.type]);
 
2719
                        break;
 
2720
 
 
2721
                case Hwindows:
 
2722
                        // Windows TLS base is always 0x14(FS).
 
2723
                        pp.from = p->from;
 
2724
                        pp.from.type = D_INDIR+D_FS;
 
2725
                        pp.from.offset = 0x14;
 
2726
                        pp.from.index = D_NONE;
 
2727
                        pp.from.scale = 0;
 
2728
                        *ctxt->andptr++ = 0x64; // FS
 
2729
                        *ctxt->andptr++ = 0x8B;
 
2730
                        asmand(ctxt, &pp.from, reg[p->to.type]);
 
2731
                        break;
 
2732
                }
 
2733
                break;
 
2734
        }
 
2735
}
 
2736
 
 
2737
static uchar naclret[] = {
 
2738
        0x5d, // POPL BP
 
2739
        // 0x8b, 0x7d, 0x00, // MOVL (BP), DI - catch return to invalid address, for debugging
 
2740
        0x83, 0xe5, 0xe0,       // ANDL $~31, BP
 
2741
        0xff, 0xe5, // JMP BP
 
2742
};
 
2743
 
 
2744
static void
 
2745
asmins(Link *ctxt, Prog *p)
 
2746
{
 
2747
        Reloc *r;
 
2748
 
 
2749
        ctxt->andptr = ctxt->and;
 
2750
        
 
2751
        if(p->as == AUSEFIELD) {
 
2752
                r = addrel(ctxt->cursym);
 
2753
                r->off = 0;
 
2754
                r->sym = p->from.sym;
 
2755
                r->type = R_USEFIELD;
 
2756
                r->siz = 0;
 
2757
                return;
 
2758
        }
 
2759
 
 
2760
        if(ctxt->headtype == Hnacl) {
 
2761
                switch(p->as) {
 
2762
                case ARET:
 
2763
                        memmove(ctxt->andptr, naclret, sizeof naclret);
 
2764
                        ctxt->andptr += sizeof naclret;
 
2765
                        return;
 
2766
                case ACALL:
 
2767
                case AJMP:
 
2768
                        if(D_AX <= p->to.type && p->to.type <= D_DI) {
 
2769
                                *ctxt->andptr++ = 0x83;
 
2770
                                *ctxt->andptr++ = 0xe0 | (p->to.type - D_AX);
 
2771
                                *ctxt->andptr++ = 0xe0;
 
2772
                        }
 
2773
                        break;
 
2774
                case AINT:
 
2775
                        *ctxt->andptr++ = 0xf4;
 
2776
                        return;
 
2777
                }
 
2778
        }
 
2779
 
 
2780
        doasm(ctxt, p);
 
2781
        if(ctxt->andptr > ctxt->and+sizeof ctxt->and) {
 
2782
                print("and[] is too short - %ld byte instruction\n", ctxt->andptr - ctxt->and);
 
2783
                sysfatal("bad code");
 
2784
        }
 
2785
}