386.mx raw

   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