github.com/dylandreimerink/gobpfld@v0.6.1-0.20220205171531-e79c330ad608/ebpf/asm.go (about) 1 package ebpf 2 3 import ( 4 "fmt" 5 "io" 6 "strconv" 7 "strings" 8 9 "github.com/alecthomas/participle/v2" 10 "github.com/alecthomas/participle/v2/lexer/stateful" 11 ) 12 13 var ( 14 ebpfLexer = stateful.MustSimple([]stateful.Rule{ 15 {Name: "Comment", Pattern: `(?:#)[^\n]*`, Action: nil}, 16 {Name: "Register32", Pattern: `w[0-9]{1,2}`, Action: nil}, 17 {Name: "Register64", Pattern: `r[0-9]{1,2}`, Action: nil}, 18 // https://golang.org/pkg/strconv/#ParseInt 19 {Name: "Number", Pattern: `(0x[0-9a-fA-F]+)|(0b[01]+)|(0o?[0-7]+)|\d+`, Action: nil}, 20 {Name: "Nop", Pattern: `nop`, Action: nil}, 21 {Name: "Ident", Pattern: `[a-zA-Z0-9_]+`, Action: nil}, 22 {Name: "LabelEnd", Pattern: `:`, Action: nil}, 23 {Name: "Punct", Pattern: `[-[!@#$%^&*()+_={}\\\|;'"<,>.?/]|]`, Action: nil}, 24 {Name: "Whitespace", Pattern: `[ \t\r]+`, Action: nil}, 25 {Name: "Newline", Pattern: `\n`, Action: nil}, 26 }) 27 ebpfParser = participle.MustBuild(&asmFile{}, 28 participle.Lexer(ebpfLexer), 29 participle.Elide("Comment", "Whitespace", "Nop"), 30 participle.UseLookahead(100), 31 ) 32 ) 33 34 // TODO make a AssemblyToProgram function, since we can technically reconstruct the whole ELF(Program, Maps, license) 35 // from the assembly 36 37 // AssemblyToInstructions takes in a reader and the name of the file which is used in error messages. This function 38 // attempts to parse the contents of the file as a super set of clang/LLVM eBPF assembly code. Meaning that 39 // we support the output of clang with the -S option and some additional features since clang/LLVM doesn't 40 // generate or assemble all instructions in the eBPF specification. 41 func AssemblyToInstructions(filename string, reader io.Reader) ([]Instruction, error) { 42 ast := &asmFile{} 43 err := ebpfParser.Parse(filename, reader, ast) 44 if err != nil { 45 return nil, fmt.Errorf("error while parsing: %w", err) 46 } 47 48 var instructions []Instruction 49 50 ctx := assembleContext{ 51 Labels: make(map[string]int), 52 Maps: make(map[string]struct{}), 53 } 54 55 instCnt := 0 56 for _, entry := range ast.Entries { 57 if entry.Label != "" { 58 if _, found := ctx.Labels[entry.Label]; found { 59 return nil, fmt.Errorf("duplicate label '%s' found, labels must be unique", entry.Label) 60 } 61 62 ctx.Labels[entry.Label] = instCnt 63 continue 64 } 65 66 if entry.Instruction != nil { 67 // Since the LoadConstant64bit is the only instruction to produce 2 instructions, we have to account for 68 // that when counting 69 if entry.Instruction.LoadConstant64bit != nil { 70 instCnt++ 71 } 72 73 instCnt++ 74 continue 75 } 76 77 if entry.Directive != nil { 78 if typ := entry.Directive.Type; typ != nil { 79 // object type declarations are maps(as far as I can tell, we may need to check size, 80 // and section as well in future) 81 if typ.Type == "object" { 82 if _, found := ctx.Maps[typ.Name]; found { 83 return nil, fmt.Errorf("duplicate map definition '%s'", typ.Name) 84 } 85 86 ctx.Maps[typ.Name] = struct{}{} 87 } 88 } 89 90 continue 91 } 92 } 93 94 instCnt = 0 95 for _, entry := range ast.Entries { 96 if entry.Instruction != nil { 97 insts, err := entry.Instruction.ToInst(instCnt, &ctx) 98 if err != nil { 99 return nil, err 100 } 101 102 instructions = append(instructions, insts...) 103 instCnt++ 104 105 // Since the LoadConstant64bit is the only instruction to produce 2 instructions, we have to account for 106 // that when counting 107 if entry.Instruction.LoadConstant64bit != nil { 108 instCnt++ 109 } 110 } 111 } 112 113 return instructions, nil 114 } 115 116 type assembleContext struct { 117 Labels map[string]int 118 Maps map[string]struct{} // TODO add actual parsed map definition in the future? 119 } 120 121 type asmFile struct { 122 Entries []*entry `parser:"@@*"` 123 } 124 125 type entry struct { 126 Label string `parser:"( @(Ident|Number|Punct)+ LabelEnd"` 127 Directive *directive `parser:"| @@"` 128 Instruction *instruction `parser:"| @@ )? Newline*"` 129 } 130 131 func (r *Register) Capture(values []string) error { 132 // Join all values, and strip the leading r 133 i, err := strconv.Atoi(strings.Join(values, "")[1:]) 134 if err != nil { 135 return err 136 } 137 138 *r = Register(i) 139 140 return nil 141 } 142 143 func (s *Size) Capture(values []string) error { 144 switch strings.Join(values, "") { 145 case "u8", "w8": 146 *s = BPF_B 147 case "u16", "w16": 148 *s = BPF_H 149 case "u32", "w32": 150 *s = BPF_W 151 case "u64", "w64": 152 *s = BPF_DW 153 default: 154 return fmt.Errorf("'%s' is not a valid variable Size", strings.Join(values, "")) 155 } 156 157 return nil 158 } 159 160 type directive struct { 161 Type *typeDirective `parser:" @@"` 162 Generic *genericDirective `parser:"| @@"` 163 } 164 165 // https://sourceware.org/binutils/docs/as/Type.html 166 type typeDirective struct { 167 Name string `parser:"'.' 'type' @Ident"` 168 Type string `parser:"','? ('@'|'%')? @Ident"` 169 } 170 171 type genericDirective struct { 172 Name string `parser:"'.' @Ident"` 173 Value string `parser:"(@Ident | @Number | @Punct)*"` 174 } 175 176 type instruction struct { 177 ARSH32 *arsh32 `parser:" @@"` 178 ARSH32Register *arsh32Register `parser:"| @@"` 179 ARSH64 *arsh64 `parser:"| @@"` 180 ARSH64Register *arsh64Register `parser:"| @@"` 181 Add32 *add32 `parser:"| @@"` 182 Add32Register *add32Register `parser:"| @@"` 183 Add64 *add64 `parser:"| @@"` 184 Add64Register *add64Register `parser:"| @@"` 185 And32 *and32 `parser:"| @@"` 186 And32Register *and32Register `parser:"| @@"` 187 And64 *and64 `parser:"| @@"` 188 And64Register *and64Register `parser:"| @@"` 189 AtomicAdd32 *atomicAdd32 `parser:"| @@"` 190 AtomicAdd64 *atomicAdd64 `parser:"| @@"` 191 AtomicSub32 *atomicSub32 `parser:"| @@"` 192 AtomicSub64 *atomicSub64 `parser:"| @@"` 193 AtomicAnd32 *atomicAnd32 `parser:"| @@"` 194 AtomicAnd64 *atomicAnd64 `parser:"| @@"` 195 AtomicCompareAndExchange32 *atomicCompareAndExchange32 `parser:"| @@"` 196 AtomicCompareAndExchange64 *atomicCompareAndExchange64 `parser:"| @@"` 197 AtomicExchange32 *atomicExchange32 `parser:"| @@"` 198 AtomicExchange64 *atomicExchange64 `parser:"| @@"` 199 AtomicOr32 *atomicOr32 `parser:"| @@"` 200 AtomicOr64 *atomicOr64 `parser:"| @@"` 201 AtomicXor32 *atomicXor32 `parser:"| @@"` 202 AtomicXor64 *atomicXor64 `parser:"| @@"` 203 Call *call `parser:"| @@"` 204 Div32 *div32 `parser:"| @@"` 205 Div32Register *div32Register `parser:"| @@"` 206 Div64 *div64 `parser:"| @@"` 207 Div64Register *div64Register `parser:"| @@"` 208 End16ToBE *end16ToBE `parser:"| @@"` 209 End16ToLE *end16ToLE `parser:"| @@"` 210 End32ToBE *end32ToBE `parser:"| @@"` 211 End32ToLE *end32ToLE `parser:"| @@"` 212 End64ToBE *end64ToBE `parser:"| @@"` 213 End64ToLE *end64ToLE `parser:"| @@"` 214 Exit *exit `parser:"| @@"` 215 Jump *jump `parser:"| @@"` 216 JumpEqual *jumpEqual `parser:"| @@"` 217 JumpEqual32 *jumpEqual32 `parser:"| @@"` 218 JumpEqualRegister *jumpEqualRegister `parser:"| @@"` 219 JumpEqualRegister32 *jumpEqualRegister32 `parser:"| @@"` 220 JumpGreaterThan *jumpGreaterThan `parser:"| @@"` 221 JumpGreaterThan32 *jumpGreaterThan32 `parser:"| @@"` 222 JumpGreaterThanRegister *jumpGreaterThanRegister `parser:"| @@"` 223 JumpGreaterThanRegister32 *jumpGreaterThanRegister32 `parser:"| @@"` 224 JumpGreaterThanEqual *jumpGreaterThanEqual `parser:"| @@"` 225 JumpGreaterThanEqual32 *jumpGreaterThanEqual32 `parser:"| @@"` 226 JumpGreaterThanEqualRegister *jumpGreaterThanEqualRegister `parser:"| @@"` 227 JumpGreaterThanEqualRegister32 *jumpGreaterThanEqualRegister32 `parser:"| @@"` 228 JumpIfAnd *jumpIfAnd `parser:"| @@"` 229 JumpIfAnd32 *jumpIfAnd32 `parser:"| @@"` 230 JumpIfAndRegister *jumpIfAndRegister `parser:"| @@"` 231 JumpIfAndRegister32 *jumpIfAndRegister32 `parser:"| @@"` 232 JumpIfNotEqual *jumpIfNotEqual `parser:"| @@"` 233 JumpIfNotEqual32 *jumpIfNotEqual32 `parser:"| @@"` 234 JumpIfNotEqualRegister *jumpIfNotEqualRegister `parser:"| @@"` 235 JumpIfNotEqualRegister32 *jumpIfNotEqualRegister32 `parser:"| @@"` 236 JumpSignedGreaterThan *jumpSignedGreaterThan `parser:"| @@"` 237 JumpSignedGreaterThan32 *jumpSignedGreaterThan32 `parser:"| @@"` 238 JumpSignedGreaterThanRegister *jumpSignedGreaterThanRegister `parser:"| @@"` 239 JumpSignedGreaterThanRegister32 *jumpSignedGreaterThanRegister32 `parser:"| @@"` 240 JumpSignedGreaterThanOrEqual *jumpSignedGreaterThanOrEqual `parser:"| @@"` 241 JumpSignedGreaterThanOrEqual32 *jumpSignedGreaterThanOrEqual32 `parser:"| @@"` 242 JumpSignedGreaterThanOrEqualRegister *jumpSignedGreaterThanOrEqualRegister `parser:"| @@"` 243 JumpSignedGreaterThanOrEqualRegister32 *jumpSignedGreaterThanOrEqualRegister32 `parser:"| @@"` 244 JumpSignedSmallerThan *jumpSignedSmallerThan `parser:"| @@"` 245 JumpSignedSmallerThan32 *jumpSignedSmallerThan32 `parser:"| @@"` 246 JumpSignedSmallerThanRegister *jumpSignedSmallerThanRegister `parser:"| @@"` 247 JumpSignedSmallerThanRegister32 *jumpSignedSmallerThanRegister32 `parser:"| @@"` 248 JumpSignedSmallerThanOrEqual *jumpSignedSmallerThanOrEqual `parser:"| @@"` 249 JumpSignedSmallerThanOrEqual32 *jumpSignedSmallerThanOrEqual32 `parser:"| @@"` 250 JumpSignedSmallerThanOrEqualRegister *jumpSignedSmallerThanOrEqualRegister `parser:"| @@"` 251 JumpSignedSmallerThanOrEqualRegister32 *jumpSignedSmallerThanOrEqualRegister32 `parser:"| @@"` 252 JumpSmallerThan *jumpSmallerThan `parser:"| @@"` 253 JumpSmallerThan32 *jumpSmallerThan32 `parser:"| @@"` 254 JumpSmallerThanRegister *jumpSmallerThanRegister `parser:"| @@"` 255 JumpSmallerThanRegister32 *jumpSmallerThanRegister32 `parser:"| @@"` 256 JumpSmallerThanEqual *jumpSmallerThanEqual `parser:"| @@"` 257 JumpSmallerThanEqual32 *jumpSmallerThanEqual32 `parser:"| @@"` 258 JumpSmallerThanEqualRegister *jumpSmallerThanEqualRegister `parser:"| @@"` 259 JumpSmallerThanEqualRegister32 *jumpSmallerThanEqualRegister32 `parser:"| @@"` 260 LoadConstant64bit *loadConstant64bit `parser:"| @@"` 261 LoadMemory *loadMemory `parser:"| @@"` 262 LoadSocketBuf *loadSocketBuf `parser:"| @@"` 263 LoadSocketBufConstant *loadSocketBufConstant `parser:"| @@"` 264 Lsh32 *lsh32 `parser:"| @@"` 265 Lsh32Register *lsh32Register `parser:"| @@"` 266 Lsh64 *lsh64 `parser:"| @@"` 267 Lsh64Register *lsh64Register `parser:"| @@"` 268 Mod32 *mod32 `parser:"| @@"` 269 Mod32Register *mod32Register `parser:"| @@"` 270 Mod64 *mod64 `parser:"| @@"` 271 Mod64Register *mod64Register `parser:"| @@"` 272 Mov32 *mov32 `parser:"| @@"` 273 Mov32Register *mov32Register `parser:"| @@"` 274 Mov64 *mov64 `parser:"| @@"` 275 Mov64Register *mov64Register `parser:"| @@"` 276 Mul32 *mul32 `parser:"| @@"` 277 Mul32Register *mul32Register `parser:"| @@"` 278 Mul64 *mul64 `parser:"| @@"` 279 Mul64Register *mul64Register `parser:"| @@"` 280 Neg32 *neg32 `parser:"| @@"` 281 Neg64 *neg64 `parser:"| @@"` 282 Or32 *or32 `parser:"| @@"` 283 Or32Register *or32Register `parser:"| @@"` 284 Or64 *or64 `parser:"| @@"` 285 Or64Register *or64Register `parser:"| @@"` 286 Rsh32 *rsh32 `parser:"| @@"` 287 Rsh32Register *rsh32Register `parser:"| @@"` 288 Rsh64 *rsh64 `parser:"| @@"` 289 Rsh64Register *rsh64Register `parser:"| @@"` 290 StoreMemoryConstant *storeMemoryConstant `parser:"| @@"` 291 StoreMemoryRegister *storeMemoryRegister `parser:"| @@"` 292 Sub32 *sub32 `parser:"| @@"` 293 Sub32Register *sub32Register `parser:"| @@"` 294 Sub64 *sub64 `parser:"| @@"` 295 Sub64Register *sub64Register `parser:"| @@"` 296 Xor32 *xor32 `parser:"| @@"` 297 Xor32Register *xor32Register `parser:"| @@"` 298 Xor64 *xor64 `parser:"| @@"` 299 Xor64Register *xor64Register `parser:"| @@"` 300 } 301 302 func (i *instruction) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 303 if i.ARSH32 != nil { 304 return i.ARSH32.ToInst(index, ctx) 305 } 306 307 if i.ARSH32Register != nil { 308 return i.ARSH32Register.ToInst(index, ctx) 309 } 310 311 if i.ARSH64 != nil { 312 return i.ARSH64.ToInst(index, ctx) 313 } 314 315 if i.ARSH64Register != nil { 316 return i.ARSH64Register.ToInst(index, ctx) 317 } 318 319 if i.Add32 != nil { 320 return i.Add32.ToInst(index, ctx) 321 } 322 323 if i.Add32Register != nil { 324 return i.Add32Register.ToInst(index, ctx) 325 } 326 327 if i.Add64 != nil { 328 return i.Add64.ToInst(index, ctx) 329 } 330 331 if i.Add64Register != nil { 332 return i.Add64Register.ToInst(index, ctx) 333 } 334 335 if i.And32 != nil { 336 return i.And32.ToInst(index, ctx) 337 } 338 339 if i.And32Register != nil { 340 return i.And32Register.ToInst(index, ctx) 341 } 342 343 if i.And64 != nil { 344 return i.And64.ToInst(index, ctx) 345 } 346 347 if i.And64Register != nil { 348 return i.And64Register.ToInst(index, ctx) 349 } 350 351 if i.AtomicAdd32 != nil { 352 return i.AtomicAdd32.ToInst(index, ctx) 353 } 354 355 if i.AtomicAdd64 != nil { 356 return i.AtomicAdd64.ToInst(index, ctx) 357 } 358 359 if i.AtomicSub32 != nil { 360 return i.AtomicSub32.ToInst(index, ctx) 361 } 362 363 if i.AtomicSub64 != nil { 364 return i.AtomicSub64.ToInst(index, ctx) 365 } 366 367 if i.AtomicAnd32 != nil { 368 return i.AtomicAnd32.ToInst(index, ctx) 369 } 370 371 if i.AtomicAnd64 != nil { 372 return i.AtomicAnd64.ToInst(index, ctx) 373 } 374 375 if i.AtomicCompareAndExchange32 != nil { 376 return i.AtomicCompareAndExchange32.ToInst(index, ctx) 377 } 378 379 if i.AtomicCompareAndExchange64 != nil { 380 return i.AtomicCompareAndExchange64.ToInst(index, ctx) 381 } 382 383 if i.AtomicExchange32 != nil { 384 return i.AtomicExchange32.ToInst(index, ctx) 385 } 386 387 if i.AtomicExchange64 != nil { 388 return i.AtomicExchange64.ToInst(index, ctx) 389 } 390 391 if i.AtomicOr32 != nil { 392 return i.AtomicOr32.ToInst(index, ctx) 393 } 394 395 if i.AtomicOr64 != nil { 396 return i.AtomicOr64.ToInst(index, ctx) 397 } 398 399 if i.AtomicXor32 != nil { 400 return i.AtomicXor32.ToInst(index, ctx) 401 } 402 403 if i.AtomicXor64 != nil { 404 return i.AtomicXor64.ToInst(index, ctx) 405 } 406 407 if i.Call != nil { 408 return i.Call.ToInst(index, ctx) 409 } 410 411 if i.Div32 != nil { 412 return i.Div32.ToInst(index, ctx) 413 } 414 415 if i.Div32Register != nil { 416 return i.Div32Register.ToInst(index, ctx) 417 } 418 419 if i.Div64 != nil { 420 return i.Div64.ToInst(index, ctx) 421 } 422 423 if i.Div64Register != nil { 424 return i.Div64Register.ToInst(index, ctx) 425 } 426 427 if i.End16ToBE != nil { 428 return i.End16ToBE.ToInst(index, ctx) 429 } 430 431 if i.End16ToLE != nil { 432 return i.End16ToLE.ToInst(index, ctx) 433 } 434 435 if i.End32ToBE != nil { 436 return i.End32ToBE.ToInst(index, ctx) 437 } 438 439 if i.End32ToLE != nil { 440 return i.End32ToLE.ToInst(index, ctx) 441 } 442 443 if i.End64ToBE != nil { 444 return i.End64ToBE.ToInst(index, ctx) 445 } 446 447 if i.End64ToLE != nil { 448 return i.End64ToLE.ToInst(index, ctx) 449 } 450 451 if i.Exit != nil { 452 return i.Exit.ToInst(index, ctx) 453 } 454 455 if i.Jump != nil { 456 return i.Jump.ToInst(index, ctx) 457 } 458 459 if i.JumpEqual != nil { 460 return i.JumpEqual.ToInst(index, ctx) 461 } 462 463 if i.JumpEqual32 != nil { 464 return i.JumpEqual32.ToInst(index, ctx) 465 } 466 467 if i.JumpEqualRegister != nil { 468 return i.JumpEqualRegister.ToInst(index, ctx) 469 } 470 471 if i.JumpEqualRegister32 != nil { 472 return i.JumpEqualRegister32.ToInst(index, ctx) 473 } 474 475 if i.JumpGreaterThan != nil { 476 return i.JumpGreaterThan.ToInst(index, ctx) 477 } 478 479 if i.JumpGreaterThan32 != nil { 480 return i.JumpGreaterThan32.ToInst(index, ctx) 481 } 482 483 if i.JumpGreaterThanRegister != nil { 484 return i.JumpGreaterThanRegister.ToInst(index, ctx) 485 } 486 487 if i.JumpGreaterThanRegister32 != nil { 488 return i.JumpGreaterThanRegister32.ToInst(index, ctx) 489 } 490 491 if i.JumpGreaterThanEqual != nil { 492 return i.JumpGreaterThanEqual.ToInst(index, ctx) 493 } 494 495 if i.JumpGreaterThanEqual32 != nil { 496 return i.JumpGreaterThanEqual32.ToInst(index, ctx) 497 } 498 499 if i.JumpGreaterThanEqualRegister != nil { 500 return i.JumpGreaterThanEqualRegister.ToInst(index, ctx) 501 } 502 503 if i.JumpGreaterThanEqualRegister32 != nil { 504 return i.JumpGreaterThanEqualRegister32.ToInst(index, ctx) 505 } 506 507 if i.JumpIfAnd != nil { 508 return i.JumpIfAnd.ToInst(index, ctx) 509 } 510 511 if i.JumpIfAnd32 != nil { 512 return i.JumpIfAnd32.ToInst(index, ctx) 513 } 514 515 if i.JumpIfAndRegister != nil { 516 return i.JumpIfAndRegister.ToInst(index, ctx) 517 } 518 519 if i.JumpIfAndRegister32 != nil { 520 return i.JumpIfAndRegister32.ToInst(index, ctx) 521 } 522 523 if i.JumpIfNotEqual != nil { 524 return i.JumpIfNotEqual.ToInst(index, ctx) 525 } 526 527 if i.JumpIfNotEqual32 != nil { 528 return i.JumpIfNotEqual32.ToInst(index, ctx) 529 } 530 531 if i.JumpIfNotEqualRegister != nil { 532 return i.JumpIfNotEqualRegister.ToInst(index, ctx) 533 } 534 535 if i.JumpIfNotEqualRegister32 != nil { 536 return i.JumpIfNotEqualRegister32.ToInst(index, ctx) 537 } 538 539 if i.JumpSignedGreaterThan != nil { 540 return i.JumpSignedGreaterThan.ToInst(index, ctx) 541 } 542 543 if i.JumpSignedGreaterThan32 != nil { 544 return i.JumpSignedGreaterThan32.ToInst(index, ctx) 545 } 546 547 if i.JumpSignedGreaterThanRegister != nil { 548 return i.JumpSignedGreaterThanRegister.ToInst(index, ctx) 549 } 550 551 if i.JumpSignedGreaterThanRegister32 != nil { 552 return i.JumpSignedGreaterThanRegister32.ToInst(index, ctx) 553 } 554 555 if i.JumpSignedGreaterThanOrEqual != nil { 556 return i.JumpSignedGreaterThanOrEqual.ToInst(index, ctx) 557 } 558 559 if i.JumpSignedGreaterThanOrEqual32 != nil { 560 return i.JumpSignedGreaterThanOrEqual32.ToInst(index, ctx) 561 } 562 563 if i.JumpSignedGreaterThanOrEqualRegister != nil { 564 return i.JumpSignedGreaterThanOrEqualRegister.ToInst(index, ctx) 565 } 566 567 if i.JumpSignedGreaterThanOrEqualRegister32 != nil { 568 return i.JumpSignedGreaterThanOrEqualRegister32.ToInst(index, ctx) 569 } 570 571 if i.JumpSignedSmallerThan != nil { 572 return i.JumpSignedSmallerThan.ToInst(index, ctx) 573 } 574 575 if i.JumpSignedSmallerThan32 != nil { 576 return i.JumpSignedSmallerThan32.ToInst(index, ctx) 577 } 578 579 if i.JumpSignedSmallerThanRegister != nil { 580 return i.JumpSignedSmallerThanRegister.ToInst(index, ctx) 581 } 582 583 if i.JumpSignedSmallerThanRegister32 != nil { 584 return i.JumpSignedSmallerThanRegister32.ToInst(index, ctx) 585 } 586 587 if i.JumpSignedSmallerThanOrEqual != nil { 588 return i.JumpSignedSmallerThanOrEqual.ToInst(index, ctx) 589 } 590 591 if i.JumpSignedSmallerThanOrEqual32 != nil { 592 return i.JumpSignedSmallerThanOrEqual32.ToInst(index, ctx) 593 } 594 595 if i.JumpSignedSmallerThanOrEqualRegister != nil { 596 return i.JumpSignedSmallerThanOrEqualRegister.ToInst(index, ctx) 597 } 598 599 if i.JumpSignedSmallerThanOrEqualRegister32 != nil { 600 return i.JumpSignedSmallerThanOrEqualRegister32.ToInst(index, ctx) 601 } 602 603 if i.JumpSmallerThan != nil { 604 return i.JumpSmallerThan.ToInst(index, ctx) 605 } 606 607 if i.JumpSmallerThan32 != nil { 608 return i.JumpSmallerThan32.ToInst(index, ctx) 609 } 610 611 if i.JumpSmallerThanRegister != nil { 612 return i.JumpSmallerThanRegister.ToInst(index, ctx) 613 } 614 615 if i.JumpSmallerThanRegister32 != nil { 616 return i.JumpSmallerThanRegister32.ToInst(index, ctx) 617 } 618 619 if i.JumpSmallerThanEqual != nil { 620 return i.JumpSmallerThanEqual.ToInst(index, ctx) 621 } 622 623 if i.JumpSmallerThanEqual32 != nil { 624 return i.JumpSmallerThanEqual32.ToInst(index, ctx) 625 } 626 627 if i.JumpSmallerThanEqualRegister != nil { 628 return i.JumpSmallerThanEqualRegister.ToInst(index, ctx) 629 } 630 631 if i.JumpSmallerThanEqualRegister32 != nil { 632 return i.JumpSmallerThanEqualRegister32.ToInst(index, ctx) 633 } 634 635 if i.LoadConstant64bit != nil { 636 return i.LoadConstant64bit.ToInst(index, ctx) 637 } 638 639 if i.LoadMemory != nil { 640 return i.LoadMemory.ToInst(index, ctx) 641 } 642 643 if i.LoadSocketBuf != nil { 644 return i.LoadSocketBuf.ToInst(index, ctx) 645 } 646 647 if i.LoadSocketBufConstant != nil { 648 return i.LoadSocketBufConstant.ToInst(index, ctx) 649 } 650 651 if i.Lsh32 != nil { 652 return i.Lsh32.ToInst(index, ctx) 653 } 654 655 if i.Lsh32Register != nil { 656 return i.Lsh32Register.ToInst(index, ctx) 657 } 658 659 if i.Lsh64 != nil { 660 return i.Lsh64.ToInst(index, ctx) 661 } 662 663 if i.Lsh64Register != nil { 664 return i.Lsh64Register.ToInst(index, ctx) 665 } 666 667 if i.Mod32 != nil { 668 return i.Mod32.ToInst(index, ctx) 669 } 670 671 if i.Mod32Register != nil { 672 return i.Mod32Register.ToInst(index, ctx) 673 } 674 675 if i.Mod64 != nil { 676 return i.Mod64.ToInst(index, ctx) 677 } 678 679 if i.Mod64Register != nil { 680 return i.Mod64Register.ToInst(index, ctx) 681 } 682 683 if i.Mov32 != nil { 684 return i.Mov32.ToInst(index, ctx) 685 } 686 687 if i.Mov32Register != nil { 688 return i.Mov32Register.ToInst(index, ctx) 689 } 690 691 if i.Mov64 != nil { 692 return i.Mov64.ToInst(index, ctx) 693 } 694 695 if i.Mov64Register != nil { 696 return i.Mov64Register.ToInst(index, ctx) 697 } 698 699 if i.Mul32 != nil { 700 return i.Mul32.ToInst(index, ctx) 701 } 702 703 if i.Mul32Register != nil { 704 return i.Mul32Register.ToInst(index, ctx) 705 } 706 707 if i.Mul64 != nil { 708 return i.Mul64.ToInst(index, ctx) 709 } 710 711 if i.Mul64Register != nil { 712 return i.Mul64Register.ToInst(index, ctx) 713 } 714 715 if i.Neg32 != nil { 716 return i.Neg32.ToInst(index, ctx) 717 } 718 719 if i.Neg64 != nil { 720 return i.Neg64.ToInst(index, ctx) 721 } 722 723 if i.Or32 != nil { 724 return i.Or32.ToInst(index, ctx) 725 } 726 727 if i.Or32Register != nil { 728 return i.Or32Register.ToInst(index, ctx) 729 } 730 731 if i.Or64 != nil { 732 return i.Or64.ToInst(index, ctx) 733 } 734 735 if i.Or64Register != nil { 736 return i.Or64Register.ToInst(index, ctx) 737 } 738 739 if i.Rsh32 != nil { 740 return i.Rsh32.ToInst(index, ctx) 741 } 742 743 if i.Rsh32Register != nil { 744 return i.Rsh32Register.ToInst(index, ctx) 745 } 746 747 if i.Rsh64 != nil { 748 return i.Rsh64.ToInst(index, ctx) 749 } 750 751 if i.Rsh64Register != nil { 752 return i.Rsh64Register.ToInst(index, ctx) 753 } 754 755 if i.StoreMemoryConstant != nil { 756 return i.StoreMemoryConstant.ToInst(index, ctx) 757 } 758 759 if i.StoreMemoryRegister != nil { 760 return i.StoreMemoryRegister.ToInst(index, ctx) 761 } 762 763 if i.Sub32 != nil { 764 return i.Sub32.ToInst(index, ctx) 765 } 766 767 if i.Sub32Register != nil { 768 return i.Sub32Register.ToInst(index, ctx) 769 } 770 771 if i.Sub64 != nil { 772 return i.Sub64.ToInst(index, ctx) 773 } 774 775 if i.Sub64Register != nil { 776 return i.Sub64Register.ToInst(index, ctx) 777 } 778 779 if i.Xor32 != nil { 780 return i.Xor32.ToInst(index, ctx) 781 } 782 783 if i.Xor32Register != nil { 784 return i.Xor32Register.ToInst(index, ctx) 785 } 786 787 if i.Xor64 != nil { 788 return i.Xor64.ToInst(index, ctx) 789 } 790 791 if i.Xor64Register != nil { 792 return i.Xor64Register.ToInst(index, ctx) 793 } 794 795 return nil, nil 796 } 797 798 type arsh32 struct { 799 Dst Register `parser:"@Register32 's' '>' '>' '='"` 800 Value int32 `parser:"@(('+'|'-')? Number)"` 801 } 802 803 func (i *arsh32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 804 return []Instruction{&ARSH32{ 805 Dest: i.Dst, 806 Value: i.Value, 807 }}, nil 808 } 809 810 type arsh32Register struct { 811 Dst Register `parser:"@Register32 's' '>' '>' '='"` 812 Src Register `parser:"@Register32"` 813 } 814 815 func (i *arsh32Register) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 816 return []Instruction{ 817 &ARSH32Register{ 818 Dest: i.Dst, 819 Src: i.Src, 820 }, 821 }, nil 822 } 823 824 type arsh64 struct { 825 Dst Register `parser:"@Register64 's' '>' '>' '='"` 826 Value int32 `parser:"@(('+'|'-')? Number)"` 827 } 828 829 func (i *arsh64) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 830 return []Instruction{&ARSH64{ 831 Dest: i.Dst, 832 Value: i.Value, 833 }}, nil 834 } 835 836 type arsh64Register struct { 837 Dst Register `parser:"@Register64 's' '>' '>' '='"` 838 Src Register `parser:"@Register64"` 839 } 840 841 func (i *arsh64Register) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 842 return []Instruction{&ARSH64Register{ 843 Dest: i.Dst, 844 Src: i.Src, 845 }}, nil 846 } 847 848 type add32 struct { 849 Dst Register `parser:"@Register32 '+' '='"` 850 Value int32 `parser:"@(('+'|'-')? Number)"` 851 } 852 853 func (i *add32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 854 return []Instruction{&Add32{ 855 Dest: i.Dst, 856 Value: i.Value, 857 }}, nil 858 } 859 860 type add32Register struct { 861 Dst Register `parser:"@Register32 '+' '='"` 862 Src Register `parser:"@Register32"` 863 } 864 865 func (i *add32Register) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 866 return []Instruction{&Add32Register{ 867 Dest: i.Dst, 868 Src: i.Src, 869 }}, nil 870 } 871 872 type add64 struct { 873 Dst Register `parser:"@Register64 '+' '='"` 874 Value int32 `parser:"@(('+'|'-')? Number)"` 875 } 876 877 func (i *add64) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 878 return []Instruction{&Add64{ 879 Dest: i.Dst, 880 Value: i.Value, 881 }}, nil 882 } 883 884 type add64Register struct { 885 Dst Register `parser:"@Register64 '+' '='"` 886 Src Register `parser:"@Register64"` 887 } 888 889 func (i *add64Register) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 890 return []Instruction{&Add64Register{ 891 Dest: i.Dst, 892 Src: i.Src, 893 }}, nil 894 } 895 896 type and32 struct { 897 Dst Register `parser:"@Register32 '&' '='"` 898 Value int32 `parser:"@(('+'|'-')? Number)"` 899 } 900 901 func (i *and32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 902 return []Instruction{&And32{ 903 Dest: i.Dst, 904 Value: i.Value, 905 }}, nil 906 } 907 908 type and32Register struct { 909 Dst Register `parser:"@Register32 '&' '='"` 910 Src Register `parser:"@Register32"` 911 } 912 913 func (i *and32Register) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 914 return []Instruction{&And32Register{ 915 Dest: i.Dst, 916 Src: i.Src, 917 }}, nil 918 } 919 920 type and64 struct { 921 Dst Register `parser:"@Register64 '&' '='"` 922 Value int32 `parser:"@(('+'|'-')? Number)"` 923 } 924 925 func (i *and64) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 926 return []Instruction{&And64{ 927 Dest: i.Dst, 928 Value: i.Value, 929 }}, nil 930 } 931 932 type and64Register struct { 933 Dst Register `parser:"@Register64 '&' '='"` 934 Src Register `parser:"@Register64"` 935 } 936 937 func (i *and64Register) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 938 return []Instruction{&And64Register{ 939 Dest: i.Dst, 940 Src: i.Src, 941 }}, nil 942 } 943 944 type atomicAdd32 struct { 945 Dst Register `parser:"'lock' '*' '(' 'u32' '*' ')' '(' @Register64"` 946 Offset int32 `parser:"@(('+'|'-') Number) ')' '+' '='"` 947 Src Register `parser:"@Register32"` 948 } 949 950 func (i *atomicAdd32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 951 return []Instruction{&AtomicAdd{ 952 Dest: i.Dst, 953 Src: i.Src, 954 Size: BPF_W, 955 Offset: int16(i.Offset), 956 Fetch: false, // TODO make a special instruction for the fetch flag? 957 }}, nil 958 } 959 960 type atomicAdd64 struct { 961 Dst Register `parser:"'lock' '*' '(' 'u64' '*' ')' '(' @Register64"` 962 Offset int32 `parser:"@(('+'|'-') Number) ')' '+' '='"` 963 Src Register `parser:"@Register64"` 964 } 965 966 func (i *atomicAdd64) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 967 return []Instruction{&AtomicAdd{ 968 Dest: i.Dst, 969 Src: i.Src, 970 Size: BPF_DW, 971 Offset: int16(i.Offset), 972 Fetch: false, // TODO make a special instruction for the fetch flag? 973 }}, nil 974 } 975 976 type atomicSub32 struct { 977 Dst Register `parser:"'lock' '*' '(' 'u32' '*' ')' '(' @Register64"` 978 Offset int32 `parser:"@(('+'|'-') Number) ')' '-' '='"` 979 Src Register `parser:"@Register32"` 980 } 981 982 func (i *atomicSub32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 983 return []Instruction{&AtomicSub{ 984 Dest: i.Dst, 985 Src: i.Src, 986 Size: BPF_W, 987 Offset: int16(i.Offset), 988 Fetch: false, // TODO make a special instruction for the fetch flag? 989 }}, nil 990 } 991 992 type atomicSub64 struct { 993 Dst Register `parser:"'lock' '*' '(' 'u64' '*' ')' '(' @Register64"` 994 Offset int32 `parser:"@(('+'|'-') Number) ')' '-' '='"` 995 Src Register `parser:"@Register64"` 996 } 997 998 func (i *atomicSub64) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 999 return []Instruction{&AtomicSub{ 1000 Dest: i.Dst, 1001 Src: i.Src, 1002 Size: BPF_DW, 1003 Offset: int16(i.Offset), 1004 Fetch: false, // TODO make a special instruction for the fetch flag? 1005 }}, nil 1006 } 1007 1008 type atomicAnd32 struct { 1009 Dst Register `parser:"'lock' '*' '(' 'u32' '*' ')' '(' @Register64"` 1010 Offset int32 `parser:"@(('+'|'-') Number) ')' '&' '='"` 1011 Src Register `parser:"@Register32"` 1012 } 1013 1014 func (i *atomicAnd32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1015 return []Instruction{&AtomicAnd{ 1016 Dest: i.Dst, 1017 Src: i.Src, 1018 Size: BPF_W, 1019 Offset: int16(i.Offset), 1020 Fetch: false, // TODO make a special instruction for the fetch flag? 1021 }}, nil 1022 } 1023 1024 type atomicAnd64 struct { 1025 Dst Register `parser:"'lock' '*' '(' 'u64' '*' ')' '(' @Register64"` 1026 Offset int32 `parser:"@(('+'|'-') Number) ')' '&' '='"` 1027 Src Register `parser:"@Register64"` 1028 } 1029 1030 func (i *atomicAnd64) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1031 return []Instruction{&AtomicAnd{ 1032 Dest: i.Dst, 1033 Src: i.Src, 1034 Size: BPF_DW, 1035 Offset: int16(i.Offset), 1036 Fetch: false, // TODO make a special instruction for the fetch flag? 1037 }}, nil 1038 } 1039 1040 // w0 = cmpxchg(r3 + 456, w0, w2) 1041 type atomicCompareAndExchange32 struct { 1042 Dst Register `parser:"'w0' '=' 'cmpxchg' '(' @Register64"` 1043 Offset int32 `parser:"@(('+'|'-') Number) ',' 'w0' ','"` 1044 Src Register `parser:"@Register32 ')'"` 1045 } 1046 1047 func (i *atomicCompareAndExchange32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1048 return []Instruction{&AtomicCompareAndExchange{ 1049 Dest: i.Dst, 1050 Src: i.Src, 1051 Size: BPF_W, 1052 Offset: int16(i.Offset), 1053 }}, nil 1054 } 1055 1056 // r0 = cmpxchg(r3 + 456, r0, r2) 1057 type atomicCompareAndExchange64 struct { 1058 Dst Register `parser:"'r0' '=' 'cmpxchg' '(' @Register64"` 1059 Offset int32 `parser:"@(('+'|'-') Number) ',' 'r0' ','"` 1060 Src Register `parser:"@Register64 ')'"` 1061 } 1062 1063 func (i *atomicCompareAndExchange64) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1064 return []Instruction{&AtomicCompareAndExchange{ 1065 Dest: i.Dst, 1066 Src: i.Src, 1067 Size: BPF_DW, 1068 Offset: int16(i.Offset), 1069 }}, nil 1070 } 1071 1072 // w1 = xchg(r3 + 456, w1) 1073 type atomicExchange32 struct { 1074 Src Register `parser:"@Register32 '=' 'xchg' '('"` 1075 Dst Register `parser:"@Register64"` 1076 Offset int32 `parser:"@(('+'|'-') Number) ',' Register32 ')'"` 1077 } 1078 1079 func (i *atomicExchange32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1080 return []Instruction{&AtomicExchange{ 1081 Dest: i.Dst, 1082 Src: i.Src, 1083 Size: BPF_W, 1084 Offset: int16(i.Offset), 1085 }}, nil 1086 } 1087 1088 // r1 = xchg(r3 + 456, r1) 1089 type atomicExchange64 struct { 1090 Src Register `parser:"@Register64 '=' 'xchg' '('"` 1091 Dst Register `parser:"@Register64"` 1092 Offset int32 `parser:"@(('+'|'-') Number) ',' Register64 ')'"` 1093 } 1094 1095 func (i *atomicExchange64) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1096 return []Instruction{&AtomicExchange{ 1097 Dest: i.Dst, 1098 Src: i.Src, 1099 Size: BPF_DW, 1100 Offset: int16(i.Offset), 1101 }}, nil 1102 } 1103 1104 type atomicOr32 struct { 1105 Dst Register `parser:"'lock' '*' '(' 'u32' '*' ')' '(' @Register64"` 1106 Offset int32 `parser:"@(('+'|'-') Number) ')' '|' '='"` 1107 Src Register `parser:"@Register32"` 1108 } 1109 1110 func (i *atomicOr32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1111 return []Instruction{&AtomicOr{ 1112 Dest: i.Dst, 1113 Src: i.Src, 1114 Size: BPF_W, 1115 Offset: int16(i.Offset), 1116 Fetch: false, // TODO make a special instruction for the fetch flag? 1117 }}, nil 1118 } 1119 1120 type atomicOr64 struct { 1121 Dst Register `parser:"'lock' '*' '(' 'u64' '*' ')' '(' @Register64"` 1122 Offset int32 `parser:"@(('+'|'-') Number) ')' '|' '='"` 1123 Src Register `parser:"@Register64"` 1124 } 1125 1126 func (i *atomicOr64) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1127 return []Instruction{&AtomicOr{ 1128 Dest: i.Dst, 1129 Src: i.Src, 1130 Size: BPF_DW, 1131 Offset: int16(i.Offset), 1132 Fetch: false, // TODO make a special instruction for the fetch flag? 1133 }}, nil 1134 } 1135 1136 type atomicXor32 struct { 1137 Dst Register `parser:"'lock' '*' '(' 'u32' '*' ')' '(' @Register64"` 1138 Offset int32 `parser:"@(('+'|'-') Number) ')' '^' '='"` 1139 Src Register `parser:"@Register32"` 1140 } 1141 1142 func (i *atomicXor32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1143 return []Instruction{&AtomicXor{ 1144 Dest: i.Dst, 1145 Src: i.Src, 1146 Size: BPF_W, 1147 Offset: int16(i.Offset), 1148 Fetch: false, // TODO make a special instruction for the fetch flag? 1149 }}, nil 1150 } 1151 1152 type atomicXor64 struct { 1153 Dst Register `parser:"'lock' '*' '(' 'u64' '*' ')' '(' @Register64"` 1154 Offset int32 `parser:"@(('+'|'-') Number) ')' '^' '='"` 1155 Src Register `parser:"@Register64"` 1156 } 1157 1158 func (i *atomicXor64) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1159 return []Instruction{&AtomicXor{ 1160 Dest: i.Dst, 1161 Src: i.Src, 1162 Size: BPF_DW, 1163 Offset: int16(i.Offset), 1164 Fetch: false, // TODO make a special instruction for the fetch flag? 1165 }}, nil 1166 } 1167 1168 // Call is both for BPF-to-BPF and helper funcs, but since 1169 type call struct { 1170 Ident *string `parser:"'call' (@Ident |"` 1171 Offset *int32 `parser:"@(('+'|'-') Number) |"` 1172 HelperNum *int32 `parser:"@Number)"` 1173 } 1174 1175 func (i *call) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1176 if i.Ident != nil { 1177 pos, found := ctx.Labels[*i.Ident] 1178 if !found { 1179 // TODO check if the ident matches a known helper function 1180 1181 return nil, fmt.Errorf("undefined label '%s'", *i.Ident) 1182 } 1183 1184 off := int32(pos-index) - 1 1185 i.Offset = &off 1186 } 1187 1188 if i.Offset != nil { 1189 return []Instruction{&CallBPF{ 1190 Offset: *i.Offset, 1191 }}, nil 1192 } 1193 1194 if i.HelperNum != nil { 1195 return []Instruction{&CallHelper{ 1196 Function: *i.HelperNum, 1197 }}, nil 1198 } 1199 1200 return nil, nil 1201 } 1202 1203 type div32 struct { 1204 Dst Register `parser:"@Register32 '/' '='"` 1205 Value int32 `parser:"@(('+'|'-')? Number)"` 1206 } 1207 1208 func (i *div32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1209 return []Instruction{&Div32{ 1210 Dest: i.Dst, 1211 Value: i.Value, 1212 }}, nil 1213 } 1214 1215 type div32Register struct { 1216 Dst Register `parser:"@Register32 '/' '='"` 1217 Src Register `parser:"@Register32"` 1218 } 1219 1220 func (i *div32Register) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1221 return []Instruction{&Div32Register{ 1222 Dest: i.Dst, 1223 Src: i.Src, 1224 }}, nil 1225 } 1226 1227 type div64 struct { 1228 Dst Register `parser:"@Register64 '/' '='"` 1229 Value int32 `parser:"@(('+'|'-')? Number)"` 1230 } 1231 1232 func (i *div64) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1233 return []Instruction{&Div64{ 1234 Dest: i.Dst, 1235 Value: i.Value, 1236 }}, nil 1237 } 1238 1239 type div64Register struct { 1240 Dst Register `parser:"@Register64 '/' '='"` 1241 Src Register `parser:"@Register64"` 1242 } 1243 1244 func (i *div64Register) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1245 return []Instruction{&Div64Register{ 1246 Dest: i.Dst, 1247 Src: i.Src, 1248 }}, nil 1249 } 1250 1251 type end16ToBE struct { 1252 Dst Register `parser:"@Register64 '=' 'be16' Register64"` 1253 } 1254 1255 func (i *end16ToBE) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1256 return []Instruction{&End16ToBE{ 1257 Dest: i.Dst, 1258 }}, nil 1259 } 1260 1261 type end16ToLE struct { 1262 Dst Register `parser:"@Register64 '=' 'le16' Register64"` 1263 } 1264 1265 func (i *end16ToLE) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1266 return []Instruction{&End16ToLE{ 1267 Dest: i.Dst, 1268 }}, nil 1269 } 1270 1271 type end32ToBE struct { 1272 Dst Register `parser:"@Register64 '=' 'be32' Register64"` 1273 } 1274 1275 func (i *end32ToBE) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1276 return []Instruction{&End32ToBE{ 1277 Dest: i.Dst, 1278 }}, nil 1279 } 1280 1281 type end32ToLE struct { 1282 Dst Register `parser:"@Register64 '=' 'le32' Register64"` 1283 } 1284 1285 func (i *end32ToLE) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1286 return []Instruction{&End32ToLE{ 1287 Dest: i.Dst, 1288 }}, nil 1289 } 1290 1291 type end64ToBE struct { 1292 Dst Register `parser:"@Register64 '=' 'be64' Register64"` 1293 } 1294 1295 func (i *end64ToBE) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1296 return []Instruction{&End64ToBE{ 1297 Dest: i.Dst, 1298 }}, nil 1299 } 1300 1301 type end64ToLE struct { 1302 Dst Register `parser:"@Register64 '=' 'le64' Register64"` 1303 } 1304 1305 func (i *end64ToLE) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1306 return []Instruction{&End64ToLE{ 1307 Dest: i.Dst, 1308 }}, nil 1309 } 1310 1311 type exit struct { 1312 Exit struct{} `parser:"'exit'"` 1313 } 1314 1315 func (i *exit) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1316 return []Instruction{&Exit{}}, nil 1317 } 1318 1319 type jump struct { 1320 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 1321 Label *string `parser:"@Ident )"` 1322 } 1323 1324 func (i *jump) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1325 inst := &Jump{} 1326 1327 if i.Label != nil { 1328 target, found := ctx.Labels[*i.Label] 1329 if !found { 1330 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 1331 } 1332 1333 // Get diff between current instruction and the target, -1 since a offset of 0 will jump 1334 // to the next instruction (inherent pc+1) 1335 inst.Offset = int16(target-index) - 1 1336 } 1337 1338 if i.Offset != nil { 1339 inst.Offset = *i.Offset 1340 } 1341 1342 return []Instruction{inst}, nil 1343 } 1344 1345 type jumpEqual struct { 1346 Dest Register `parser:"'if' @Register64 '=' '=' "` 1347 Value int32 `parser:"@(('+'|'-')? Number)"` 1348 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 1349 Label *string `parser:"@Ident )"` 1350 } 1351 1352 func (i *jumpEqual) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1353 inst := &JumpEqual{ 1354 Dest: i.Dest, 1355 Value: i.Value, 1356 } 1357 1358 if i.Label != nil { 1359 target, found := ctx.Labels[*i.Label] 1360 if !found { 1361 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 1362 } 1363 1364 // Get diff between current instruction and the target 1365 inst.Offset = int16(target-index) - 1 1366 } 1367 1368 if i.Offset != nil { 1369 inst.Offset = *i.Offset 1370 } 1371 1372 return []Instruction{inst}, nil 1373 } 1374 1375 type jumpEqual32 struct { 1376 Dest Register `parser:"'if' @Register32 '=' '=' "` 1377 Value int32 `parser:"@(('+'|'-')? Number)"` 1378 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 1379 Label *string `parser:"@Ident )"` 1380 } 1381 1382 func (i *jumpEqual32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1383 inst := &JumpEqual32{ 1384 Dest: i.Dest, 1385 Value: i.Value, 1386 } 1387 1388 if i.Label != nil { 1389 target, found := ctx.Labels[*i.Label] 1390 if !found { 1391 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 1392 } 1393 1394 // Get diff between current instruction and the target 1395 inst.Offset = int16(target-index) - 1 1396 } 1397 1398 if i.Offset != nil { 1399 inst.Offset = *i.Offset 1400 } 1401 1402 return []Instruction{inst}, nil 1403 } 1404 1405 type jumpEqualRegister struct { 1406 Dest Register `parser:"'if' @Register64 '=' '=' "` 1407 Src Register `parser:"@Register64"` 1408 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 1409 Label *string `parser:"@Ident )"` 1410 } 1411 1412 func (i *jumpEqualRegister) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1413 inst := &JumpEqualRegister{ 1414 Dest: i.Dest, 1415 Src: i.Src, 1416 } 1417 1418 if i.Label != nil { 1419 target, found := ctx.Labels[*i.Label] 1420 if !found { 1421 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 1422 } 1423 1424 // Get diff between current instruction and the target 1425 inst.Offset = int16(target-index) - 1 1426 } 1427 1428 if i.Offset != nil { 1429 inst.Offset = *i.Offset 1430 } 1431 1432 return []Instruction{inst}, nil 1433 } 1434 1435 type jumpEqualRegister32 struct { 1436 Dest Register `parser:"'if' @Register32 '=' '=' "` 1437 Src Register `parser:"@Register32"` 1438 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 1439 Label *string `parser:"@Ident )"` 1440 } 1441 1442 func (i *jumpEqualRegister32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1443 inst := &JumpEqualRegister32{ 1444 Dest: i.Dest, 1445 Src: i.Src, 1446 } 1447 1448 if i.Label != nil { 1449 target, found := ctx.Labels[*i.Label] 1450 if !found { 1451 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 1452 } 1453 1454 // Get diff between current instruction and the target 1455 inst.Offset = int16(target-index) - 1 1456 } 1457 1458 if i.Offset != nil { 1459 inst.Offset = *i.Offset 1460 } 1461 1462 return []Instruction{inst}, nil 1463 } 1464 1465 type jumpGreaterThan struct { 1466 Dest Register `parser:"'if' @Register64 '>' "` 1467 Value int32 `parser:"@(('+'|'-')? Number)"` 1468 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 1469 Label *string `parser:"@Ident )"` 1470 } 1471 1472 func (i *jumpGreaterThan) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1473 inst := &JumpGreaterThan{ 1474 Dest: i.Dest, 1475 Value: i.Value, 1476 } 1477 1478 if i.Label != nil { 1479 target, found := ctx.Labels[*i.Label] 1480 if !found { 1481 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 1482 } 1483 1484 // Get diff between current instruction and the target 1485 inst.Offset = int16(target-index) - 1 1486 } 1487 1488 if i.Offset != nil { 1489 inst.Offset = *i.Offset 1490 } 1491 1492 return []Instruction{inst}, nil 1493 } 1494 1495 type jumpGreaterThan32 struct { 1496 Dest Register `parser:"'if' @Register32 '>' "` 1497 Value int32 `parser:"@(('+'|'-')? Number)"` 1498 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 1499 Label *string `parser:"@Ident )"` 1500 } 1501 1502 func (i *jumpGreaterThan32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1503 inst := &JumpGreaterThan32{ 1504 Dest: i.Dest, 1505 Value: i.Value, 1506 } 1507 1508 if i.Label != nil { 1509 target, found := ctx.Labels[*i.Label] 1510 if !found { 1511 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 1512 } 1513 1514 // Get diff between current instruction and the target 1515 inst.Offset = int16(target-index) - 1 1516 } 1517 1518 if i.Offset != nil { 1519 inst.Offset = *i.Offset 1520 } 1521 1522 return []Instruction{inst}, nil 1523 } 1524 1525 type jumpGreaterThanRegister struct { 1526 Dest Register `parser:"'if' @Register64 '>' "` 1527 Src Register `parser:"@Register64"` 1528 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 1529 Label *string `parser:"@Ident )"` 1530 } 1531 1532 func (i *jumpGreaterThanRegister) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1533 inst := &JumpGreaterThanRegister{ 1534 Dest: i.Dest, 1535 Src: i.Src, 1536 } 1537 1538 if i.Label != nil { 1539 target, found := ctx.Labels[*i.Label] 1540 if !found { 1541 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 1542 } 1543 1544 // Get diff between current instruction and the target 1545 inst.Offset = int16(target-index) - 1 1546 } 1547 1548 if i.Offset != nil { 1549 inst.Offset = *i.Offset 1550 } 1551 1552 return []Instruction{inst}, nil 1553 } 1554 1555 type jumpGreaterThanRegister32 struct { 1556 Dest Register `parser:"'if' @Register32 '>' "` 1557 Src Register `parser:"@Register32"` 1558 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 1559 Label *string `parser:"@Ident )"` 1560 } 1561 1562 func (i *jumpGreaterThanRegister32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1563 inst := &JumpGreaterThanRegister32{ 1564 Dest: i.Dest, 1565 Src: i.Src, 1566 } 1567 1568 if i.Label != nil { 1569 target, found := ctx.Labels[*i.Label] 1570 if !found { 1571 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 1572 } 1573 1574 // Get diff between current instruction and the target 1575 inst.Offset = int16(target-index) - 1 1576 } 1577 1578 if i.Offset != nil { 1579 inst.Offset = *i.Offset 1580 } 1581 1582 return []Instruction{inst}, nil 1583 } 1584 1585 type jumpGreaterThanEqual struct { 1586 Dest Register `parser:"'if' @Register64 '>' '='"` 1587 Value int32 `parser:"@(('+'|'-')? Number)"` 1588 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 1589 Label *string `parser:"@Ident )"` 1590 } 1591 1592 func (i *jumpGreaterThanEqual) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1593 inst := &JumpGreaterThanEqual{ 1594 Dest: i.Dest, 1595 Value: i.Value, 1596 } 1597 1598 if i.Label != nil { 1599 target, found := ctx.Labels[*i.Label] 1600 if !found { 1601 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 1602 } 1603 1604 // Get diff between current instruction and the target 1605 inst.Offset = int16(target-index) - 1 1606 } 1607 1608 if i.Offset != nil { 1609 inst.Offset = *i.Offset 1610 } 1611 1612 return []Instruction{inst}, nil 1613 } 1614 1615 type jumpGreaterThanEqual32 struct { 1616 Dest Register `parser:"'if' @Register32 '>' '='"` 1617 Value int32 `parser:"@(('+'|'-')? Number)"` 1618 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 1619 Label *string `parser:"@Ident )"` 1620 } 1621 1622 func (i *jumpGreaterThanEqual32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1623 inst := &JumpGreaterThanEqual32{ 1624 Dest: i.Dest, 1625 Value: i.Value, 1626 } 1627 1628 if i.Label != nil { 1629 target, found := ctx.Labels[*i.Label] 1630 if !found { 1631 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 1632 } 1633 1634 // Get diff between current instruction and the target 1635 inst.Offset = int16(target-index) - 1 1636 } 1637 1638 if i.Offset != nil { 1639 inst.Offset = *i.Offset 1640 } 1641 1642 return []Instruction{inst}, nil 1643 } 1644 1645 type jumpGreaterThanEqualRegister struct { 1646 Dest Register `parser:"'if' @Register64 '>' '='"` 1647 Src Register `parser:"@Register64"` 1648 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 1649 Label *string `parser:"@Ident )"` 1650 } 1651 1652 func (i *jumpGreaterThanEqualRegister) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1653 inst := &JumpGreaterThanEqualRegister{ 1654 Dest: i.Dest, 1655 Src: i.Src, 1656 } 1657 1658 if i.Label != nil { 1659 target, found := ctx.Labels[*i.Label] 1660 if !found { 1661 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 1662 } 1663 1664 // Get diff between current instruction and the target 1665 inst.Offset = int16(target-index) - 1 1666 } 1667 1668 if i.Offset != nil { 1669 inst.Offset = *i.Offset 1670 } 1671 1672 return []Instruction{inst}, nil 1673 } 1674 1675 type jumpGreaterThanEqualRegister32 struct { 1676 Dest Register `parser:"'if' @Register32 '>' '=' "` 1677 Src Register `parser:"@Register32"` 1678 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 1679 Label *string `parser:"@Ident )"` 1680 } 1681 1682 func (i *jumpGreaterThanEqualRegister32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1683 inst := &JumpGreaterThanEqualRegister32{ 1684 Dest: i.Dest, 1685 Src: i.Src, 1686 } 1687 1688 if i.Label != nil { 1689 target, found := ctx.Labels[*i.Label] 1690 if !found { 1691 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 1692 } 1693 1694 // Get diff between current instruction and the target 1695 inst.Offset = int16(target-index) - 1 1696 } 1697 1698 if i.Offset != nil { 1699 inst.Offset = *i.Offset 1700 } 1701 1702 return []Instruction{inst}, nil 1703 } 1704 1705 type jumpIfAnd struct { 1706 Dest Register `parser:"'if' @Register64 '&' "` 1707 Value int32 `parser:"@(('+'|'-')? Number)"` 1708 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 1709 Label *string `parser:"@Ident )"` 1710 } 1711 1712 func (i *jumpIfAnd) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1713 inst := &JumpAnd{ 1714 Dest: i.Dest, 1715 Value: i.Value, 1716 } 1717 1718 if i.Label != nil { 1719 target, found := ctx.Labels[*i.Label] 1720 if !found { 1721 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 1722 } 1723 1724 // Get diff between current instruction and the target 1725 inst.Offset = int16(target-index) - 1 1726 } 1727 1728 if i.Offset != nil { 1729 inst.Offset = *i.Offset 1730 } 1731 1732 return []Instruction{inst}, nil 1733 } 1734 1735 type jumpIfAnd32 struct { 1736 Dest Register `parser:"'if' @Register32 '&' "` 1737 Value int32 `parser:"@(('+'|'-')? Number)"` 1738 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 1739 Label *string `parser:"@Ident )"` 1740 } 1741 1742 func (i *jumpIfAnd32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1743 inst := &JumpAnd32{ 1744 Dest: i.Dest, 1745 Value: i.Value, 1746 } 1747 1748 if i.Label != nil { 1749 target, found := ctx.Labels[*i.Label] 1750 if !found { 1751 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 1752 } 1753 1754 // Get diff between current instruction and the target 1755 inst.Offset = int16(target-index) - 1 1756 } 1757 1758 if i.Offset != nil { 1759 inst.Offset = *i.Offset 1760 } 1761 1762 return []Instruction{inst}, nil 1763 } 1764 1765 type jumpIfAndRegister struct { 1766 Dest Register `parser:"'if' @Register64 '&' "` 1767 Src Register `parser:"@Register64"` 1768 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 1769 Label *string `parser:"@Ident )"` 1770 } 1771 1772 func (i *jumpIfAndRegister) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1773 inst := &JumpAndRegister{ 1774 Dest: i.Dest, 1775 Src: i.Src, 1776 } 1777 1778 if i.Label != nil { 1779 target, found := ctx.Labels[*i.Label] 1780 if !found { 1781 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 1782 } 1783 1784 // Get diff between current instruction and the target 1785 inst.Offset = int16(target-index) - 1 1786 } 1787 1788 if i.Offset != nil { 1789 inst.Offset = *i.Offset 1790 } 1791 1792 return []Instruction{inst}, nil 1793 } 1794 1795 type jumpIfAndRegister32 struct { 1796 Dest Register `parser:"'if' @Register32 '&' "` 1797 Src Register `parser:"@Register32"` 1798 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 1799 Label *string `parser:"@Ident )"` 1800 } 1801 1802 func (i *jumpIfAndRegister32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1803 inst := &JumpAndRegister32{ 1804 Dest: i.Dest, 1805 Src: i.Src, 1806 } 1807 1808 if i.Label != nil { 1809 target, found := ctx.Labels[*i.Label] 1810 if !found { 1811 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 1812 } 1813 1814 // Get diff between current instruction and the target 1815 inst.Offset = int16(target-index) - 1 1816 } 1817 1818 if i.Offset != nil { 1819 inst.Offset = *i.Offset 1820 } 1821 1822 return []Instruction{inst}, nil 1823 } 1824 1825 type jumpIfNotEqual struct { 1826 Dest Register `parser:"'if' @Register64 '!' '=' "` 1827 Value int32 `parser:"@(('+'|'-')? Number)"` 1828 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 1829 Label *string `parser:"@Ident )"` 1830 } 1831 1832 func (i *jumpIfNotEqual) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1833 inst := &JumpNotEqual{ 1834 Dest: i.Dest, 1835 Value: i.Value, 1836 } 1837 1838 if i.Label != nil { 1839 target, found := ctx.Labels[*i.Label] 1840 if !found { 1841 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 1842 } 1843 1844 // Get diff between current instruction and the target 1845 inst.Offset = int16(target-index) - 1 1846 } 1847 1848 if i.Offset != nil { 1849 inst.Offset = *i.Offset 1850 } 1851 1852 return []Instruction{inst}, nil 1853 } 1854 1855 type jumpIfNotEqual32 struct { 1856 Dest Register `parser:"'if' @Register32 '!' '=' "` 1857 Value int32 `parser:"@(('+'|'-')? Number)"` 1858 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 1859 Label *string `parser:"@Ident )"` 1860 } 1861 1862 func (i *jumpIfNotEqual32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1863 inst := &JumpNotEqual32{ 1864 Dest: i.Dest, 1865 Value: i.Value, 1866 } 1867 1868 if i.Label != nil { 1869 target, found := ctx.Labels[*i.Label] 1870 if !found { 1871 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 1872 } 1873 1874 // Get diff between current instruction and the target 1875 inst.Offset = int16(target-index) - 1 1876 } 1877 1878 if i.Offset != nil { 1879 inst.Offset = *i.Offset 1880 } 1881 1882 return []Instruction{inst}, nil 1883 } 1884 1885 type jumpIfNotEqualRegister struct { 1886 Dest Register `parser:"'if' @Register64 '!' '=' "` 1887 Src Register `parser:"@Register64"` 1888 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 1889 Label *string `parser:"@Ident )"` 1890 } 1891 1892 func (i *jumpIfNotEqualRegister) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1893 inst := &JumpNotEqualRegister{ 1894 Dest: i.Dest, 1895 Src: i.Src, 1896 } 1897 1898 if i.Label != nil { 1899 target, found := ctx.Labels[*i.Label] 1900 if !found { 1901 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 1902 } 1903 1904 // Get diff between current instruction and the target 1905 inst.Offset = int16(target-index) - 1 1906 } 1907 1908 if i.Offset != nil { 1909 inst.Offset = *i.Offset 1910 } 1911 1912 return []Instruction{inst}, nil 1913 } 1914 1915 type jumpIfNotEqualRegister32 struct { 1916 Dest Register `parser:"'if' @Register32 '!' '=' "` 1917 Src Register `parser:"@Register32"` 1918 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 1919 Label *string `parser:"@Ident )"` 1920 } 1921 1922 func (i *jumpIfNotEqualRegister32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1923 inst := &JumpNotEqualRegister32{ 1924 Dest: i.Dest, 1925 Src: i.Src, 1926 } 1927 1928 if i.Label != nil { 1929 target, found := ctx.Labels[*i.Label] 1930 if !found { 1931 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 1932 } 1933 1934 // Get diff between current instruction and the target 1935 inst.Offset = int16(target-index) - 1 1936 } 1937 1938 if i.Offset != nil { 1939 inst.Offset = *i.Offset 1940 } 1941 1942 return []Instruction{inst}, nil 1943 } 1944 1945 type jumpSignedGreaterThan struct { 1946 Dest Register `parser:"'if' @Register64 's' '>' "` 1947 Value int32 `parser:"@(('+'|'-')? Number)"` 1948 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 1949 Label *string `parser:"@Ident )"` 1950 } 1951 1952 func (i *jumpSignedGreaterThan) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1953 inst := &JumpSignedGreaterThan{ 1954 Dest: i.Dest, 1955 Value: i.Value, 1956 } 1957 1958 if i.Label != nil { 1959 target, found := ctx.Labels[*i.Label] 1960 if !found { 1961 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 1962 } 1963 1964 // Get diff between current instruction and the target 1965 inst.Offset = int16(target-index) - 1 1966 } 1967 1968 if i.Offset != nil { 1969 inst.Offset = *i.Offset 1970 } 1971 1972 return []Instruction{inst}, nil 1973 } 1974 1975 type jumpSignedGreaterThan32 struct { 1976 Dest Register `parser:"'if' @Register32 's' '>' "` 1977 Value int32 `parser:"@(('+'|'-')? Number)"` 1978 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 1979 Label *string `parser:"@Ident )"` 1980 } 1981 1982 func (i *jumpSignedGreaterThan32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 1983 inst := &JumpSignedGreaterThan32{ 1984 Dest: i.Dest, 1985 Value: i.Value, 1986 } 1987 1988 if i.Label != nil { 1989 target, found := ctx.Labels[*i.Label] 1990 if !found { 1991 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 1992 } 1993 1994 // Get diff between current instruction and the target 1995 inst.Offset = int16(target-index) - 1 1996 } 1997 1998 if i.Offset != nil { 1999 inst.Offset = *i.Offset 2000 } 2001 2002 return []Instruction{inst}, nil 2003 } 2004 2005 type jumpSignedGreaterThanRegister struct { 2006 Dest Register `parser:"'if' @Register64 's' '>' "` 2007 Src Register `parser:"@Register64"` 2008 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 2009 Label *string `parser:"@Ident )"` 2010 } 2011 2012 func (i *jumpSignedGreaterThanRegister) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2013 inst := &JumpSignedGreaterThanRegister{ 2014 Dest: i.Dest, 2015 Src: i.Src, 2016 } 2017 2018 if i.Label != nil { 2019 target, found := ctx.Labels[*i.Label] 2020 if !found { 2021 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 2022 } 2023 2024 // Get diff between current instruction and the target 2025 inst.Offset = int16(target-index) - 1 2026 } 2027 2028 if i.Offset != nil { 2029 inst.Offset = *i.Offset 2030 } 2031 2032 return []Instruction{inst}, nil 2033 } 2034 2035 type jumpSignedGreaterThanRegister32 struct { 2036 Dest Register `parser:"'if' @Register32 's' '>' "` 2037 Src Register `parser:"@Register32"` 2038 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 2039 Label *string `parser:"@Ident )"` 2040 } 2041 2042 func (i *jumpSignedGreaterThanRegister32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2043 inst := &JumpSignedGreaterThanRegister32{ 2044 Dest: i.Dest, 2045 Src: i.Src, 2046 } 2047 2048 if i.Label != nil { 2049 target, found := ctx.Labels[*i.Label] 2050 if !found { 2051 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 2052 } 2053 2054 // Get diff between current instruction and the target 2055 inst.Offset = int16(target-index) - 1 2056 } 2057 2058 if i.Offset != nil { 2059 inst.Offset = *i.Offset 2060 } 2061 2062 return []Instruction{inst}, nil 2063 } 2064 2065 type jumpSignedGreaterThanOrEqual struct { 2066 Dest Register `parser:"'if' @Register64 's' '>' '='"` 2067 Value int32 `parser:"@(('+'|'-')? Number)"` 2068 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 2069 Label *string `parser:"@Ident )"` 2070 } 2071 2072 func (i *jumpSignedGreaterThanOrEqual) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2073 inst := &JumpSignedGreaterThanOrEqual{ 2074 Dest: i.Dest, 2075 Value: i.Value, 2076 } 2077 2078 if i.Label != nil { 2079 target, found := ctx.Labels[*i.Label] 2080 if !found { 2081 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 2082 } 2083 2084 // Get diff between current instruction and the target 2085 inst.Offset = int16(target-index) - 1 2086 } 2087 2088 if i.Offset != nil { 2089 inst.Offset = *i.Offset 2090 } 2091 2092 return []Instruction{inst}, nil 2093 } 2094 2095 type jumpSignedGreaterThanOrEqual32 struct { 2096 Dest Register `parser:"'if' @Register32 's' '>' '='"` 2097 Value int32 `parser:"@(('+'|'-')? Number)"` 2098 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 2099 Label *string `parser:"@Ident )"` 2100 } 2101 2102 func (i *jumpSignedGreaterThanOrEqual32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2103 inst := &JumpSignedGreaterThanOrEqual32{ 2104 Dest: i.Dest, 2105 Value: i.Value, 2106 } 2107 2108 if i.Label != nil { 2109 target, found := ctx.Labels[*i.Label] 2110 if !found { 2111 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 2112 } 2113 2114 // Get diff between current instruction and the target 2115 inst.Offset = int16(target-index) - 1 2116 } 2117 2118 if i.Offset != nil { 2119 inst.Offset = *i.Offset 2120 } 2121 2122 return []Instruction{inst}, nil 2123 } 2124 2125 type jumpSignedGreaterThanOrEqualRegister struct { 2126 Dest Register `parser:"'if' @Register64 's' '>' '='"` 2127 Src Register `parser:"@Register64"` 2128 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 2129 Label *string `parser:"@Ident )"` 2130 } 2131 2132 func (i *jumpSignedGreaterThanOrEqualRegister) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2133 inst := &JumpSignedGreaterThanOrEqualRegister{ 2134 Dest: i.Dest, 2135 Src: i.Src, 2136 } 2137 2138 if i.Label != nil { 2139 target, found := ctx.Labels[*i.Label] 2140 if !found { 2141 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 2142 } 2143 2144 // Get diff between current instruction and the target 2145 inst.Offset = int16(target-index) - 1 2146 } 2147 2148 if i.Offset != nil { 2149 inst.Offset = *i.Offset 2150 } 2151 2152 return []Instruction{inst}, nil 2153 } 2154 2155 type jumpSignedGreaterThanOrEqualRegister32 struct { 2156 Dest Register `parser:"'if' @Register32 's' '>' '=' "` 2157 Src Register `parser:"@Register32"` 2158 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 2159 Label *string `parser:"@Ident )"` 2160 } 2161 2162 func (i *jumpSignedGreaterThanOrEqualRegister32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2163 inst := &JumpSignedGreaterThanOrEqualRegister32{ 2164 Dest: i.Dest, 2165 Src: i.Src, 2166 } 2167 2168 if i.Label != nil { 2169 target, found := ctx.Labels[*i.Label] 2170 if !found { 2171 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 2172 } 2173 2174 // Get diff between current instruction and the target 2175 inst.Offset = int16(target-index) - 1 2176 } 2177 2178 if i.Offset != nil { 2179 inst.Offset = *i.Offset 2180 } 2181 2182 return []Instruction{inst}, nil 2183 } 2184 2185 type jumpSignedSmallerThan struct { 2186 Dest Register `parser:"'if' @Register64 's' '<' "` 2187 Value int32 `parser:"@(('+'|'-')? Number)"` 2188 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 2189 Label *string `parser:"@Ident )"` 2190 } 2191 2192 func (i *jumpSignedSmallerThan) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2193 inst := &JumpSignedSmallerThan{ 2194 Dest: i.Dest, 2195 Value: i.Value, 2196 } 2197 2198 if i.Label != nil { 2199 target, found := ctx.Labels[*i.Label] 2200 if !found { 2201 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 2202 } 2203 2204 // Get diff between current instruction and the target 2205 inst.Offset = int16(target-index) - 1 2206 } 2207 2208 if i.Offset != nil { 2209 inst.Offset = *i.Offset 2210 } 2211 2212 return []Instruction{inst}, nil 2213 } 2214 2215 type jumpSignedSmallerThan32 struct { 2216 Dest Register `parser:"'if' @Register32 's' '<' "` 2217 Value int32 `parser:"@(('+'|'-')? Number)"` 2218 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 2219 Label *string `parser:"@Ident )"` 2220 } 2221 2222 func (i *jumpSignedSmallerThan32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2223 inst := &JumpSignedSmallerThan32{ 2224 Dest: i.Dest, 2225 Value: i.Value, 2226 } 2227 2228 if i.Label != nil { 2229 target, found := ctx.Labels[*i.Label] 2230 if !found { 2231 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 2232 } 2233 2234 // Get diff between current instruction and the target 2235 inst.Offset = int16(target-index) - 1 2236 } 2237 2238 if i.Offset != nil { 2239 inst.Offset = *i.Offset 2240 } 2241 2242 return []Instruction{inst}, nil 2243 } 2244 2245 type jumpSignedSmallerThanRegister struct { 2246 Dest Register `parser:"'if' @Register64 's' '<' "` 2247 Src Register `parser:"@Register64"` 2248 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 2249 Label *string `parser:"@Ident )"` 2250 } 2251 2252 func (i *jumpSignedSmallerThanRegister) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2253 inst := &JumpSignedSmallerThanRegister{ 2254 Dest: i.Dest, 2255 Src: i.Src, 2256 } 2257 2258 if i.Label != nil { 2259 target, found := ctx.Labels[*i.Label] 2260 if !found { 2261 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 2262 } 2263 2264 // Get diff between current instruction and the target 2265 inst.Offset = int16(target-index) - 1 2266 } 2267 2268 if i.Offset != nil { 2269 inst.Offset = *i.Offset 2270 } 2271 2272 return []Instruction{inst}, nil 2273 } 2274 2275 type jumpSignedSmallerThanRegister32 struct { 2276 Dest Register `parser:"'if' @Register32 's' '<' "` 2277 Src Register `parser:"@Register32"` 2278 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 2279 Label *string `parser:"@Ident )"` 2280 } 2281 2282 func (i *jumpSignedSmallerThanRegister32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2283 inst := &JumpSignedSmallerThanRegister32{ 2284 Dest: i.Dest, 2285 Src: i.Src, 2286 } 2287 2288 if i.Label != nil { 2289 target, found := ctx.Labels[*i.Label] 2290 if !found { 2291 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 2292 } 2293 2294 // Get diff between current instruction and the target 2295 inst.Offset = int16(target-index) - 1 2296 } 2297 2298 if i.Offset != nil { 2299 inst.Offset = *i.Offset 2300 } 2301 2302 return []Instruction{inst}, nil 2303 } 2304 2305 type jumpSignedSmallerThanOrEqual struct { 2306 Dest Register `parser:"'if' @Register64 's' '<' '='"` 2307 Value int32 `parser:"@(('+'|'-')? Number)"` 2308 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 2309 Label *string `parser:"@Ident )"` 2310 } 2311 2312 func (i *jumpSignedSmallerThanOrEqual) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2313 inst := &JumpSignedSmallerThanOrEqual{ 2314 Dest: i.Dest, 2315 Value: i.Value, 2316 } 2317 2318 if i.Label != nil { 2319 target, found := ctx.Labels[*i.Label] 2320 if !found { 2321 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 2322 } 2323 2324 // Get diff between current instruction and the target 2325 inst.Offset = int16(target-index) - 1 2326 } 2327 2328 if i.Offset != nil { 2329 inst.Offset = *i.Offset 2330 } 2331 2332 return []Instruction{inst}, nil 2333 } 2334 2335 type jumpSignedSmallerThanOrEqual32 struct { 2336 Dest Register `parser:"'if' @Register32 's' '<' '='"` 2337 Value int32 `parser:"@(('+'|'-')? Number)"` 2338 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 2339 Label *string `parser:"@Ident )"` 2340 } 2341 2342 func (i *jumpSignedSmallerThanOrEqual32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2343 inst := &JumpSignedSmallerThanOrEqual32{ 2344 Dest: i.Dest, 2345 Value: i.Value, 2346 } 2347 2348 if i.Label != nil { 2349 target, found := ctx.Labels[*i.Label] 2350 if !found { 2351 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 2352 } 2353 2354 // Get diff between current instruction and the target 2355 inst.Offset = int16(target-index) - 1 2356 } 2357 2358 if i.Offset != nil { 2359 inst.Offset = *i.Offset 2360 } 2361 2362 return []Instruction{inst}, nil 2363 } 2364 2365 type jumpSignedSmallerThanOrEqualRegister struct { 2366 Dest Register `parser:"'if' @Register64 's' '<' '='"` 2367 Src Register `parser:"@Register64"` 2368 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 2369 Label *string `parser:"@Ident )"` 2370 } 2371 2372 func (i *jumpSignedSmallerThanOrEqualRegister) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2373 inst := &JumpSignedSmallerThanOrEqualRegister{ 2374 Dest: i.Dest, 2375 Src: i.Src, 2376 } 2377 2378 if i.Label != nil { 2379 target, found := ctx.Labels[*i.Label] 2380 if !found { 2381 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 2382 } 2383 2384 // Get diff between current instruction and the target 2385 inst.Offset = int16(target-index) - 1 2386 } 2387 2388 if i.Offset != nil { 2389 inst.Offset = *i.Offset 2390 } 2391 2392 return []Instruction{inst}, nil 2393 } 2394 2395 type jumpSignedSmallerThanOrEqualRegister32 struct { 2396 Dest Register `parser:"'if' @Register32 's' '<' '=' "` 2397 Src Register `parser:"@Register32"` 2398 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 2399 Label *string `parser:"@Ident )"` 2400 } 2401 2402 func (i *jumpSignedSmallerThanOrEqualRegister32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2403 inst := &JumpSignedSmallerThanOrEqualRegister32{ 2404 Dest: i.Dest, 2405 Src: i.Src, 2406 } 2407 2408 if i.Label != nil { 2409 target, found := ctx.Labels[*i.Label] 2410 if !found { 2411 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 2412 } 2413 2414 // Get diff between current instruction and the target 2415 inst.Offset = int16(target-index) - 1 2416 } 2417 2418 if i.Offset != nil { 2419 inst.Offset = *i.Offset 2420 } 2421 2422 return []Instruction{inst}, nil 2423 } 2424 2425 type jumpSmallerThan struct { 2426 Dest Register `parser:"'if' @Register64 '<' "` 2427 Value int32 `parser:"@(('+'|'-')? Number)"` 2428 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 2429 Label *string `parser:"@Ident )"` 2430 } 2431 2432 func (i *jumpSmallerThan) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2433 inst := &JumpSmallerThan{ 2434 Dest: i.Dest, 2435 Value: i.Value, 2436 } 2437 2438 if i.Label != nil { 2439 target, found := ctx.Labels[*i.Label] 2440 if !found { 2441 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 2442 } 2443 2444 // Get diff between current instruction and the target 2445 inst.Offset = int16(target-index) - 1 2446 } 2447 2448 if i.Offset != nil { 2449 inst.Offset = *i.Offset 2450 } 2451 2452 return []Instruction{inst}, nil 2453 } 2454 2455 type jumpSmallerThan32 struct { 2456 Dest Register `parser:"'if' @Register32 '<' "` 2457 Value int32 `parser:"@(('+'|'-')? Number)"` 2458 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 2459 Label *string `parser:"@Ident )"` 2460 } 2461 2462 func (i *jumpSmallerThan32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2463 inst := &JumpSmallerThan32{ 2464 Dest: i.Dest, 2465 Value: i.Value, 2466 } 2467 2468 if i.Label != nil { 2469 target, found := ctx.Labels[*i.Label] 2470 if !found { 2471 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 2472 } 2473 2474 // Get diff between current instruction and the target 2475 inst.Offset = int16(target-index) - 1 2476 } 2477 2478 if i.Offset != nil { 2479 inst.Offset = *i.Offset 2480 } 2481 2482 return []Instruction{inst}, nil 2483 } 2484 2485 type jumpSmallerThanRegister struct { 2486 Dest Register `parser:"'if' @Register64 '<' "` 2487 Src Register `parser:"@Register64"` 2488 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 2489 Label *string `parser:"@Ident )"` 2490 } 2491 2492 func (i *jumpSmallerThanRegister) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2493 inst := &JumpSmallerThanRegister{ 2494 Dest: i.Dest, 2495 Src: i.Src, 2496 } 2497 2498 if i.Label != nil { 2499 target, found := ctx.Labels[*i.Label] 2500 if !found { 2501 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 2502 } 2503 2504 // Get diff between current instruction and the target 2505 inst.Offset = int16(target-index) - 1 2506 } 2507 2508 if i.Offset != nil { 2509 inst.Offset = *i.Offset 2510 } 2511 2512 return []Instruction{inst}, nil 2513 } 2514 2515 type jumpSmallerThanRegister32 struct { 2516 Dest Register `parser:"'if' @Register32 '<' "` 2517 Src Register `parser:"@Register32"` 2518 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 2519 Label *string `parser:"@Ident )"` 2520 } 2521 2522 func (i *jumpSmallerThanRegister32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2523 inst := &JumpSmallerThanRegister32{ 2524 Dest: i.Dest, 2525 Src: i.Src, 2526 } 2527 2528 if i.Label != nil { 2529 target, found := ctx.Labels[*i.Label] 2530 if !found { 2531 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 2532 } 2533 2534 // Get diff between current instruction and the target 2535 inst.Offset = int16(target-index) - 1 2536 } 2537 2538 if i.Offset != nil { 2539 inst.Offset = *i.Offset 2540 } 2541 2542 return []Instruction{inst}, nil 2543 } 2544 2545 type jumpSmallerThanEqual struct { 2546 Dest Register `parser:"'if' @Register64 '<' '='"` 2547 Value int32 `parser:"@(('+'|'-')? Number)"` 2548 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 2549 Label *string `parser:"@Ident )"` 2550 } 2551 2552 func (i *jumpSmallerThanEqual) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2553 inst := &JumpSmallerThanEqual{ 2554 Dest: i.Dest, 2555 Value: i.Value, 2556 } 2557 2558 if i.Label != nil { 2559 target, found := ctx.Labels[*i.Label] 2560 if !found { 2561 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 2562 } 2563 2564 // Get diff between current instruction and the target 2565 inst.Offset = int16(target-index) - 1 2566 } 2567 2568 if i.Offset != nil { 2569 inst.Offset = *i.Offset 2570 } 2571 2572 return []Instruction{inst}, nil 2573 } 2574 2575 type jumpSmallerThanEqual32 struct { 2576 Dest Register `parser:"'if' @Register32 '<' '='"` 2577 Value int32 `parser:"@(('+'|'-')? Number)"` 2578 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 2579 Label *string `parser:"@Ident )"` 2580 } 2581 2582 func (i *jumpSmallerThanEqual32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2583 inst := &JumpSmallerThanEqual32{ 2584 Dest: i.Dest, 2585 Value: i.Value, 2586 } 2587 2588 if i.Label != nil { 2589 target, found := ctx.Labels[*i.Label] 2590 if !found { 2591 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 2592 } 2593 2594 // Get diff between current instruction and the target 2595 inst.Offset = int16(target-index) - 1 2596 } 2597 2598 if i.Offset != nil { 2599 inst.Offset = *i.Offset 2600 } 2601 2602 return []Instruction{inst}, nil 2603 } 2604 2605 type jumpSmallerThanEqualRegister struct { 2606 Dest Register `parser:"'if' @Register64 '<' '='"` 2607 Src Register `parser:"@Register64"` 2608 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 2609 Label *string `parser:"@Ident )"` 2610 } 2611 2612 func (i *jumpSmallerThanEqualRegister) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2613 inst := &JumpSmallerThanEqualRegister{ 2614 Dest: i.Dest, 2615 Src: i.Src, 2616 } 2617 2618 if i.Label != nil { 2619 target, found := ctx.Labels[*i.Label] 2620 if !found { 2621 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 2622 } 2623 2624 // Get diff between current instruction and the target 2625 inst.Offset = int16(target-index) - 1 2626 } 2627 2628 if i.Offset != nil { 2629 inst.Offset = *i.Offset 2630 } 2631 2632 return []Instruction{inst}, nil 2633 } 2634 2635 type jumpSmallerThanEqualRegister32 struct { 2636 Dest Register `parser:"'if' @Register32 '<' '=' "` 2637 Src Register `parser:"@Register32"` 2638 Offset *int16 `parser:"'goto' (@(('+'|'-')? Number) |"` 2639 Label *string `parser:"@Ident )"` 2640 } 2641 2642 func (i *jumpSmallerThanEqualRegister32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2643 inst := &JumpSmallerThanEqualRegister32{ 2644 Dest: i.Dest, 2645 Src: i.Src, 2646 } 2647 2648 if i.Label != nil { 2649 target, found := ctx.Labels[*i.Label] 2650 if !found { 2651 return nil, fmt.Errorf("invalid label '%s' at instruction %d", *i.Label, index) 2652 } 2653 2654 // Get diff between current instruction and the target 2655 inst.Offset = int16(target-index) - 1 2656 } 2657 2658 if i.Offset != nil { 2659 inst.Offset = *i.Offset 2660 } 2661 2662 return []Instruction{inst}, nil 2663 } 2664 2665 type loadConstant64bit struct { 2666 Dest Register `parser:"@Register64 '='"` 2667 Label *string `parser:"(@Ident |"` 2668 Value *int64 `parser:"@Number) 'll'"` 2669 } 2670 2671 func (i *loadConstant64bit) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2672 ld := &LoadConstant64bit{ 2673 Dest: i.Dest, 2674 } 2675 2676 if i.Value != nil { 2677 val := uint64(*i.Value) 2678 ld.Val2 = uint32((val >> 32) & 0xFFFFFFFF) 2679 ld.Val1 = uint32(val & 0xFFFFFFFF) 2680 } 2681 2682 // Since the LD instruction will generate 2 eBPF instructions, we also create the Nop instructions 2683 // which will generate no eBPF instructions. So the amount of Instructions and eBPF instructions 2684 // stay the same, makes live easier while calclulating offsets and such. 2685 return []Instruction{ld, &Nop{}}, nil 2686 } 2687 2688 type loadMemory struct { 2689 Dst Register `parser:"@Register64 '='"` 2690 Size Size `parser:"'*' '(' @Ident '*' ')' '('"` 2691 Src Register `parser:"@Register64"` 2692 Offset int16 `parser:"@(('+'|'-') Number) ')'"` 2693 } 2694 2695 func (i *loadMemory) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2696 return []Instruction{&LoadMemory{ 2697 Dest: i.Dst, 2698 Size: i.Size, 2699 Src: i.Src, 2700 Offset: i.Offset, 2701 }}, nil 2702 } 2703 2704 // r0 = ntohl((u8) (((struct sk_buff *) r6)->data[r1])) 2705 type loadSocketBuf struct { 2706 // nolint:lll // can't multi-line struct tags 2707 Size Size `parser:"'r0' '=' 'ntohl' '(' '(' @Ident ')' '(' '(' '(' 'struct' 'sk_buff' '*' ')' 'r6' ')' '-' '>' 'data' '['"` 2708 Src Register `parser:"@Register64"` 2709 Offset int32 `parser:"@(('+'|'-') Number) ']' ')' ')'"` 2710 } 2711 2712 func (i *loadSocketBuf) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2713 return []Instruction{&LoadSocketBuf{ 2714 Size: i.Size, 2715 Src: i.Src, 2716 Offset: i.Offset, 2717 }}, nil 2718 } 2719 2720 // r0 = ntohl((u8) (((struct sk_buff *) r6)->data[456])) 2721 type loadSocketBufConstant struct { 2722 // nolint:lll // can't multi-line struct tags 2723 Size Size `parser:"'r0' '=' 'ntohl' '(' '(' @Ident ')' '(' '(' '(' 'struct' 'sk_buff' '*' ')' 'r6' ')' '-' '>' 'data' '['"` 2724 Value int32 `parser:"@Number ']' ')' ')'"` 2725 } 2726 2727 func (i *loadSocketBufConstant) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2728 return []Instruction{&LoadSocketBufConstant{ 2729 Size: i.Size, 2730 Value: i.Value, 2731 }}, nil 2732 } 2733 2734 type lsh32 struct { 2735 Dst Register `parser:"@Register32 '<' '<' '='"` 2736 Value int32 `parser:"@(('+'|'-')? Number)"` 2737 } 2738 2739 func (i *lsh32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2740 return []Instruction{&Lsh32{ 2741 Dest: i.Dst, 2742 Value: i.Value, 2743 }}, nil 2744 } 2745 2746 type lsh32Register struct { 2747 Dst Register `parser:"@Register32 '<' '<' '='"` 2748 Src Register `parser:"@Register32"` 2749 } 2750 2751 func (i *lsh32Register) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2752 return []Instruction{&Lsh32Register{ 2753 Dest: i.Dst, 2754 Src: i.Src, 2755 }}, nil 2756 } 2757 2758 type lsh64 struct { 2759 Dst Register `parser:"@Register64 '<' '<' '='"` 2760 Value int32 `parser:"@(('+'|'-')? Number)"` 2761 } 2762 2763 func (i *lsh64) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2764 return []Instruction{&Lsh64{ 2765 Dest: i.Dst, 2766 Value: i.Value, 2767 }}, nil 2768 } 2769 2770 type lsh64Register struct { 2771 Dst Register `parser:"@Register64 '<' '<' '='"` 2772 Src Register `parser:"@Register64"` 2773 } 2774 2775 func (i *lsh64Register) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2776 return []Instruction{&Lsh64Register{ 2777 Dest: i.Dst, 2778 Src: i.Src, 2779 }}, nil 2780 } 2781 2782 type mod32 struct { 2783 Dst Register `parser:"@Register32 '%' '='"` 2784 Value int32 `parser:"@(('+'|'-')? Number)"` 2785 } 2786 2787 func (i *mod32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2788 return []Instruction{&Mod32{ 2789 Dest: i.Dst, 2790 Value: i.Value, 2791 }}, nil 2792 } 2793 2794 type mod32Register struct { 2795 Dst Register `parser:"@Register32 '%' '='"` 2796 Src Register `parser:"@Register32"` 2797 } 2798 2799 func (i *mod32Register) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2800 return []Instruction{&Mod32Register{ 2801 Dest: i.Dst, 2802 Src: i.Src, 2803 }}, nil 2804 } 2805 2806 type mod64 struct { 2807 Dst Register `parser:"@Register64 '%' '='"` 2808 Value int32 `parser:"@(('+'|'-')? Number)"` 2809 } 2810 2811 func (i *mod64) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2812 return []Instruction{&Mod64{ 2813 Dest: i.Dst, 2814 Value: i.Value, 2815 }}, nil 2816 } 2817 2818 type mod64Register struct { 2819 Dst Register `parser:"@Register64 '%' '='"` 2820 Src Register `parser:"@Register64"` 2821 } 2822 2823 func (i *mod64Register) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2824 return []Instruction{&Mod64Register{ 2825 Dest: i.Dst, 2826 Src: i.Src, 2827 }}, nil 2828 } 2829 2830 type mov32 struct { 2831 Dst Register `parser:"@Register32 '='"` 2832 Value int32 `parser:"@(('+'|'-')? Number)"` 2833 } 2834 2835 func (i *mov32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2836 return []Instruction{&Mov32{ 2837 Dest: i.Dst, 2838 Value: i.Value, 2839 }}, nil 2840 } 2841 2842 type mov32Register struct { 2843 Dst Register `parser:"@Register32 '='"` 2844 Src Register `parser:"@Register32"` 2845 } 2846 2847 func (i *mov32Register) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2848 return []Instruction{&Mov32Register{ 2849 Dest: i.Dst, 2850 Src: i.Src, 2851 }}, nil 2852 } 2853 2854 type mov64 struct { 2855 Dst Register `parser:"@Register64 '='"` 2856 Value int32 `parser:"@(('+'|'-')? Number)"` 2857 } 2858 2859 func (i *mov64) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2860 return []Instruction{&Mov64{ 2861 Dest: i.Dst, 2862 Value: i.Value, 2863 }}, nil 2864 } 2865 2866 type mov64Register struct { 2867 Dst Register `parser:"@Register64 '='"` 2868 Src Register `parser:"@Register64"` 2869 } 2870 2871 func (i *mov64Register) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2872 return []Instruction{&Mov64Register{ 2873 Dest: i.Dst, 2874 Src: i.Src, 2875 }}, nil 2876 } 2877 2878 type mul32 struct { 2879 Dst Register `parser:"@Register32 '*' '='"` 2880 Value int32 `parser:"@(('+'|'-')? Number)"` 2881 } 2882 2883 func (i *mul32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2884 return []Instruction{&Mul32{ 2885 Dest: i.Dst, 2886 Value: i.Value, 2887 }}, nil 2888 } 2889 2890 type mul32Register struct { 2891 Dst Register `parser:"@Register32 '*' '='"` 2892 Src Register `parser:"@Register32"` 2893 } 2894 2895 func (i *mul32Register) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2896 return []Instruction{&Mul32Register{ 2897 Dest: i.Dst, 2898 Src: i.Src, 2899 }}, nil 2900 } 2901 2902 type mul64 struct { 2903 Dst Register `parser:"@Register64 '*' '='"` 2904 Value int32 `parser:"@(('+'|'-')? Number)"` 2905 } 2906 2907 func (i *mul64) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2908 return []Instruction{&Mul64{ 2909 Dest: i.Dst, 2910 Value: i.Value, 2911 }}, nil 2912 } 2913 2914 type mul64Register struct { 2915 Dst Register `parser:"@Register64 '*' '='"` 2916 Src Register `parser:"@Register64"` 2917 } 2918 2919 func (i *mul64Register) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2920 return []Instruction{&Mul64Register{ 2921 Dest: i.Dst, 2922 Src: i.Src, 2923 }}, nil 2924 } 2925 2926 type neg32 struct { 2927 Dst Register `parser:"@Register32 '=' '-' Register32"` 2928 } 2929 2930 func (i *neg32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2931 return []Instruction{&Neg32{ 2932 Dest: i.Dst, 2933 }}, nil 2934 } 2935 2936 type neg64 struct { 2937 Dst Register `parser:"@Register64 '=' '-' Register64"` 2938 } 2939 2940 func (i *neg64) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2941 return []Instruction{&Neg64{ 2942 Dest: i.Dst, 2943 }}, nil 2944 } 2945 2946 type or32 struct { 2947 Dst Register `parser:"@Register32 '|' '='"` 2948 Value int32 `parser:"@(('+'|'-')? Number)"` 2949 } 2950 2951 func (i *or32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2952 return []Instruction{&Or32{ 2953 Dest: i.Dst, 2954 Value: i.Value, 2955 }}, nil 2956 } 2957 2958 type or32Register struct { 2959 Dst Register `parser:"@Register32 '|' '='"` 2960 Src Register `parser:"@Register32"` 2961 } 2962 2963 func (i *or32Register) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2964 return []Instruction{&Or32Register{ 2965 Dest: i.Dst, 2966 Src: i.Src, 2967 }}, nil 2968 } 2969 2970 type or64 struct { 2971 Dst Register `parser:"@Register64 '|' '='"` 2972 Value int32 `parser:"@(('+'|'-')? Number)"` 2973 } 2974 2975 func (i *or64) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2976 return []Instruction{&Or64{ 2977 Dest: i.Dst, 2978 Value: i.Value, 2979 }}, nil 2980 } 2981 2982 type or64Register struct { 2983 Dst Register `parser:"@Register64 '|' '='"` 2984 Src Register `parser:"@Register64"` 2985 } 2986 2987 func (i *or64Register) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 2988 return []Instruction{&Or64Register{ 2989 Dest: i.Dst, 2990 Src: i.Src, 2991 }}, nil 2992 } 2993 2994 type rsh32 struct { 2995 Dst Register `parser:"@Register32 '>' '>' '='"` 2996 Value int32 `parser:"@(('+'|'-')? Number)"` 2997 } 2998 2999 func (i *rsh32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 3000 return []Instruction{&Rsh32{ 3001 Dest: i.Dst, 3002 Value: i.Value, 3003 }}, nil 3004 } 3005 3006 type rsh32Register struct { 3007 Dst Register `parser:"@Register32 '>' '>' '='"` 3008 Src Register `parser:"@Register32"` 3009 } 3010 3011 func (i *rsh32Register) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 3012 return []Instruction{&Rsh32Register{ 3013 Dest: i.Dst, 3014 Src: i.Src, 3015 }}, nil 3016 } 3017 3018 type rsh64 struct { 3019 Dst Register `parser:"@Register64 '>' '>' '='"` 3020 Value int32 `parser:"@(('+'|'-')? Number)"` 3021 } 3022 3023 func (i *rsh64) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 3024 return []Instruction{&Rsh64{ 3025 Dest: i.Dst, 3026 Value: i.Value, 3027 }}, nil 3028 } 3029 3030 type rsh64Register struct { 3031 Dst Register `parser:"@Register64 '>' '>' '='"` 3032 Src Register `parser:"@Register64"` 3033 } 3034 3035 func (i *rsh64Register) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 3036 return []Instruction{&Rsh64Register{ 3037 Dest: i.Dst, 3038 Src: i.Src, 3039 }}, nil 3040 } 3041 3042 // *(u8 *)(r3 + 456) = 123 3043 type storeMemoryConstant struct { 3044 Size Size `parser:"'*' '(' @Ident '*' ')' '('"` 3045 Dst Register `parser:"@Register64"` 3046 Offset int16 `parser:"@(('+'|'-') Number) ')' '='"` 3047 Value int32 `parser:"@(('+'|'-')? Number)"` 3048 } 3049 3050 func (i *storeMemoryConstant) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 3051 return []Instruction{&StoreMemoryConstant{ 3052 Size: i.Size, 3053 Dest: i.Dst, 3054 Offset: i.Offset, 3055 Value: i.Value, 3056 }}, nil 3057 } 3058 3059 // *(u8 *)(r3 + 456) = r1 3060 type storeMemoryRegister struct { 3061 Size Size `parser:"'*' '(' @Ident '*' ')' '('"` 3062 Dst Register `parser:"@Register64"` 3063 Offset int16 `parser:"@(('+'|'-') Number) ')' '='"` 3064 Src Register `parser:"@Register64"` 3065 } 3066 3067 func (i *storeMemoryRegister) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 3068 return []Instruction{&StoreMemoryRegister{ 3069 Size: i.Size, 3070 Dest: i.Dst, 3071 Offset: i.Offset, 3072 Src: i.Src, 3073 }}, nil 3074 } 3075 3076 type sub32 struct { 3077 Dst Register `parser:"@Register32 '-' '='"` 3078 Value int32 `parser:"@(('+'|'-')? Number)"` 3079 } 3080 3081 func (i *sub32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 3082 return []Instruction{&Sub32{ 3083 Dest: i.Dst, 3084 Value: i.Value, 3085 }}, nil 3086 } 3087 3088 type sub32Register struct { 3089 Dst Register `parser:"@Register32 '-' '='"` 3090 Src Register `parser:"@Register32"` 3091 } 3092 3093 func (i *sub32Register) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 3094 return []Instruction{&Sub32Register{ 3095 Dest: i.Dst, 3096 Src: i.Src, 3097 }}, nil 3098 } 3099 3100 type sub64 struct { 3101 Dst Register `parser:"@Register64 '-' '='"` 3102 Value int32 `parser:"@(('+'|'-')? Number)"` 3103 } 3104 3105 func (i *sub64) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 3106 return []Instruction{&Sub64{ 3107 Dest: i.Dst, 3108 Value: i.Value, 3109 }}, nil 3110 } 3111 3112 type sub64Register struct { 3113 Dst Register `parser:"@Register64 '-' '='"` 3114 Src Register `parser:"@Register64"` 3115 } 3116 3117 func (i *sub64Register) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 3118 return []Instruction{&Sub64Register{ 3119 Dest: i.Dst, 3120 Src: i.Src, 3121 }}, nil 3122 } 3123 3124 type xor32 struct { 3125 Dst Register `parser:"@Register32 '^' '='"` 3126 Value int32 `parser:"@(('+'|'-')? Number)"` 3127 } 3128 3129 func (i *xor32) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 3130 return []Instruction{&Xor32{ 3131 Dest: i.Dst, 3132 Value: i.Value, 3133 }}, nil 3134 } 3135 3136 type xor32Register struct { 3137 Dst Register `parser:"@Register32 '^' '='"` 3138 Src Register `parser:"@Register32"` 3139 } 3140 3141 func (i *xor32Register) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 3142 return []Instruction{&Xor32Register{ 3143 Dest: i.Dst, 3144 Src: i.Src, 3145 }}, nil 3146 } 3147 3148 type xor64 struct { 3149 Dst Register `parser:"@Register64 '^' '='"` 3150 Value int32 `parser:"@(('+'|'-')? Number)"` 3151 } 3152 3153 func (i *xor64) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 3154 return []Instruction{&Xor64{ 3155 Dest: i.Dst, 3156 Value: i.Value, 3157 }}, nil 3158 } 3159 3160 type xor64Register struct { 3161 Dst Register `parser:"@Register64 '^' '='"` 3162 Src Register `parser:"@Register64"` 3163 } 3164 3165 func (i *xor64Register) ToInst(index int, ctx *assembleContext) ([]Instruction, error) { 3166 return []Instruction{&Xor64Register{ 3167 Dest: i.Dst, 3168 Src: i.Src, 3169 }}, nil 3170 }