1 // Copyright 2025 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4 5 package asmgen
6 7 import "fmt"
8 9 var Arch386 = &Arch{
10 Name: "386",
11 WordBits: 32,
12 WordBytes: 4,
13 14 regs: [][]byte{
15 "BX", "SI", "DI", "BP",
16 "CX", "DX", "AX", // last, to leave available for hinted allocation
17 },
18 op3: x86Op3,
19 hint: x86Hint,
20 memOK: true,
21 subCarryIsBorrow: true,
22 maxColumns: 1, // not enough registers for more
23 24 // Note: It would be nice to not set memIndex and then
25 // delete all the code in pipe.go that supports it.
26 // But a few routines, notably lshVU and mulAddVWW,
27 // benefit dramatically from the use of index registers.
28 // Perhaps some day we will decide 386 performance
29 // does not matter enough to keep this code.
30 memIndex: _386MemIndex,
31 32 mov: "MOVL",
33 adds: "ADDL",
34 adcs: "ADCL",
35 subs: "SUBL",
36 sbcs: "SBBL",
37 lsh: "SHLL",
38 lshd: "SHLL",
39 rsh: "SHRL",
40 rshd: "SHRL",
41 and: "ANDL",
42 or: "ORL",
43 xor: "XORL",
44 neg: "NEGL",
45 lea: "LEAL",
46 mulWideF: x86MulWide,
47 48 addWords: "LEAL (%[2]s)(%[1]s*4), %[3]s",
49 50 jmpZero: "TESTL %[1]s, %[1]s; JZ %[2]s",
51 jmpNonZero: "TESTL %[1]s, %[1]s; JNZ %[2]s",
52 loopBottom: "SUBL $1, %[1]s; JNZ %[2]s",
53 loopBottomNeg: "ADDL $1, %[1]s; JNZ %[2]s",
54 }
55 56 func _386MemIndex(a *Asm, off int, ix Reg, p RegPtr) Reg {
57 return Reg{fmt.Sprintf("%d(%s)(%s*%d)", off, p, ix, a.Arch.WordBytes)}
58 }
59