gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

jump.go (3424B)


      1 package asm
      2 
      3 //go:generate stringer -output jump_string.go -type=JumpOp
      4 
      5 // JumpOp affect control flow.
      6 //
      7 //    msb      lsb
      8 //    +----+-+---+
      9 //    |OP  |s|cls|
     10 //    +----+-+---+
     11 type JumpOp uint8
     12 
     13 const jumpMask OpCode = aluMask
     14 
     15 const (
     16 	// InvalidJumpOp is returned by getters when invoked
     17 	// on non branch OpCodes
     18 	InvalidJumpOp JumpOp = 0xff
     19 	// Ja jumps by offset unconditionally
     20 	Ja JumpOp = 0x00
     21 	// JEq jumps by offset if r == imm
     22 	JEq JumpOp = 0x10
     23 	// JGT jumps by offset if r > imm
     24 	JGT JumpOp = 0x20
     25 	// JGE jumps by offset if r >= imm
     26 	JGE JumpOp = 0x30
     27 	// JSet jumps by offset if r & imm
     28 	JSet JumpOp = 0x40
     29 	// JNE jumps by offset if r != imm
     30 	JNE JumpOp = 0x50
     31 	// JSGT jumps by offset if signed r > signed imm
     32 	JSGT JumpOp = 0x60
     33 	// JSGE jumps by offset if signed r >= signed imm
     34 	JSGE JumpOp = 0x70
     35 	// Call builtin or user defined function from imm
     36 	Call JumpOp = 0x80
     37 	// Exit ends execution, with value in r0
     38 	Exit JumpOp = 0x90
     39 	// JLT jumps by offset if r < imm
     40 	JLT JumpOp = 0xa0
     41 	// JLE jumps by offset if r <= imm
     42 	JLE JumpOp = 0xb0
     43 	// JSLT jumps by offset if signed r < signed imm
     44 	JSLT JumpOp = 0xc0
     45 	// JSLE jumps by offset if signed r <= signed imm
     46 	JSLE JumpOp = 0xd0
     47 )
     48 
     49 // Return emits an exit instruction.
     50 //
     51 // Requires a return value in R0.
     52 func Return() Instruction {
     53 	return Instruction{
     54 		OpCode: OpCode(JumpClass).SetJumpOp(Exit),
     55 	}
     56 }
     57 
     58 // Op returns the OpCode for a given jump source.
     59 func (op JumpOp) Op(source Source) OpCode {
     60 	return OpCode(JumpClass).SetJumpOp(op).SetSource(source)
     61 }
     62 
     63 // Imm compares 64 bit dst to 64 bit value (sign extended), and adjusts PC by offset if the condition is fulfilled.
     64 func (op JumpOp) Imm(dst Register, value int32, label string) Instruction {
     65 	return Instruction{
     66 		OpCode:   op.opCode(JumpClass, ImmSource),
     67 		Dst:      dst,
     68 		Offset:   -1,
     69 		Constant: int64(value),
     70 	}.WithReference(label)
     71 }
     72 
     73 // Imm32 compares 32 bit dst to 32 bit value, and adjusts PC by offset if the condition is fulfilled.
     74 // Requires kernel 5.1.
     75 func (op JumpOp) Imm32(dst Register, value int32, label string) Instruction {
     76 	return Instruction{
     77 		OpCode:   op.opCode(Jump32Class, ImmSource),
     78 		Dst:      dst,
     79 		Offset:   -1,
     80 		Constant: int64(value),
     81 	}.WithReference(label)
     82 }
     83 
     84 // Reg compares 64 bit dst to 64 bit src, and adjusts PC by offset if the condition is fulfilled.
     85 func (op JumpOp) Reg(dst, src Register, label string) Instruction {
     86 	return Instruction{
     87 		OpCode: op.opCode(JumpClass, RegSource),
     88 		Dst:    dst,
     89 		Src:    src,
     90 		Offset: -1,
     91 	}.WithReference(label)
     92 }
     93 
     94 // Reg32 compares 32 bit dst to 32 bit src, and adjusts PC by offset if the condition is fulfilled.
     95 // Requires kernel 5.1.
     96 func (op JumpOp) Reg32(dst, src Register, label string) Instruction {
     97 	return Instruction{
     98 		OpCode: op.opCode(Jump32Class, RegSource),
     99 		Dst:    dst,
    100 		Src:    src,
    101 		Offset: -1,
    102 	}.WithReference(label)
    103 }
    104 
    105 func (op JumpOp) opCode(class Class, source Source) OpCode {
    106 	if op == Exit || op == Call || op == Ja {
    107 		return InvalidOpCode
    108 	}
    109 
    110 	return OpCode(class).SetJumpOp(op).SetSource(source)
    111 }
    112 
    113 // Label adjusts PC to the address of the label.
    114 func (op JumpOp) Label(label string) Instruction {
    115 	if op == Call {
    116 		return Instruction{
    117 			OpCode:   OpCode(JumpClass).SetJumpOp(Call),
    118 			Src:      PseudoCall,
    119 			Constant: -1,
    120 		}.WithReference(label)
    121 	}
    122 
    123 	return Instruction{
    124 		OpCode: OpCode(JumpClass).SetJumpOp(op),
    125 		Offset: -1,
    126 	}.WithReference(label)
    127 }