alu.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. package asm
  2. //go:generate stringer -output alu_string.go -type=Source,Endianness,ALUOp
  3. // Source of ALU / ALU64 / Branch operations
  4. //
  5. // msb lsb
  6. // +----+-+---+
  7. // |op |S|cls|
  8. // +----+-+---+
  9. type Source uint8
  10. const sourceMask OpCode = 0x08
  11. // Source bitmask
  12. const (
  13. // InvalidSource is returned by getters when invoked
  14. // on non ALU / branch OpCodes.
  15. InvalidSource Source = 0xff
  16. // ImmSource src is from constant
  17. ImmSource Source = 0x00
  18. // RegSource src is from register
  19. RegSource Source = 0x08
  20. )
  21. // The Endianness of a byte swap instruction.
  22. type Endianness uint8
  23. const endianMask = sourceMask
  24. // Endian flags
  25. const (
  26. InvalidEndian Endianness = 0xff
  27. // Convert to little endian
  28. LE Endianness = 0x00
  29. // Convert to big endian
  30. BE Endianness = 0x08
  31. )
  32. // ALUOp are ALU / ALU64 operations
  33. //
  34. // msb lsb
  35. // +----+-+---+
  36. // |OP |s|cls|
  37. // +----+-+---+
  38. type ALUOp uint8
  39. const aluMask OpCode = 0xf0
  40. const (
  41. // InvalidALUOp is returned by getters when invoked
  42. // on non ALU OpCodes
  43. InvalidALUOp ALUOp = 0xff
  44. // Add - addition
  45. Add ALUOp = 0x00
  46. // Sub - subtraction
  47. Sub ALUOp = 0x10
  48. // Mul - multiplication
  49. Mul ALUOp = 0x20
  50. // Div - division
  51. Div ALUOp = 0x30
  52. // Or - bitwise or
  53. Or ALUOp = 0x40
  54. // And - bitwise and
  55. And ALUOp = 0x50
  56. // LSh - bitwise shift left
  57. LSh ALUOp = 0x60
  58. // RSh - bitwise shift right
  59. RSh ALUOp = 0x70
  60. // Neg - sign/unsign signing bit
  61. Neg ALUOp = 0x80
  62. // Mod - modulo
  63. Mod ALUOp = 0x90
  64. // Xor - bitwise xor
  65. Xor ALUOp = 0xa0
  66. // Mov - move value from one place to another
  67. Mov ALUOp = 0xb0
  68. // ArSh - arithmatic shift
  69. ArSh ALUOp = 0xc0
  70. // Swap - endian conversions
  71. Swap ALUOp = 0xd0
  72. )
  73. // HostTo converts from host to another endianness.
  74. func HostTo(endian Endianness, dst Register, size Size) Instruction {
  75. var imm int64
  76. switch size {
  77. case Half:
  78. imm = 16
  79. case Word:
  80. imm = 32
  81. case DWord:
  82. imm = 64
  83. default:
  84. return Instruction{OpCode: InvalidOpCode}
  85. }
  86. return Instruction{
  87. OpCode: OpCode(ALUClass).SetALUOp(Swap).SetSource(Source(endian)),
  88. Dst: dst,
  89. Constant: imm,
  90. }
  91. }
  92. // Op returns the OpCode for an ALU operation with a given source.
  93. func (op ALUOp) Op(source Source) OpCode {
  94. return OpCode(ALU64Class).SetALUOp(op).SetSource(source)
  95. }
  96. // Reg emits `dst (op) src`.
  97. func (op ALUOp) Reg(dst, src Register) Instruction {
  98. return Instruction{
  99. OpCode: op.Op(RegSource),
  100. Dst: dst,
  101. Src: src,
  102. }
  103. }
  104. // Imm emits `dst (op) value`.
  105. func (op ALUOp) Imm(dst Register, value int32) Instruction {
  106. return Instruction{
  107. OpCode: op.Op(ImmSource),
  108. Dst: dst,
  109. Constant: int64(value),
  110. }
  111. }
  112. // Op32 returns the OpCode for a 32-bit ALU operation with a given source.
  113. func (op ALUOp) Op32(source Source) OpCode {
  114. return OpCode(ALUClass).SetALUOp(op).SetSource(source)
  115. }
  116. // Reg32 emits `dst (op) src`, zeroing the upper 32 bit of dst.
  117. func (op ALUOp) Reg32(dst, src Register) Instruction {
  118. return Instruction{
  119. OpCode: op.Op32(RegSource),
  120. Dst: dst,
  121. Src: src,
  122. }
  123. }
  124. // Imm32 emits `dst (op) value`, zeroing the upper 32 bit of dst.
  125. func (op ALUOp) Imm32(dst Register, value int32) Instruction {
  126. return Instruction{
  127. OpCode: op.Op32(ImmSource),
  128. Dst: dst,
  129. Constant: int64(value),
  130. }
  131. }