question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Sleigh: how to specify multiple instructions within an instruction bundle?

See original GitHub issue

Hi,

I am currently attempting to add TileGx architecture to Ghidra.

I am unsure of how to define the instructor constructors as instructions are packed into 64-bit bundles containing 2-3 instructions each, depending on X or Y mode.

Example: image


Also, the instruction format bits of different instructions within a bundle may not be contiguous.

Example:

  • Y0 bits: 0-19, 27-30
  • Y1 bits: 31-50, 58-61
  • Y2 bits: 20-26, 51-57, 62-63 image

One possible solution is to define every possible permutation of instructions manually (for both X and Y mode) but that would be infeasible due to the large instruction count. Is there a better way to implement this?

My current code:

@define REGSIZE "8"
@define ADDRSIZE "8"

define endian=$(ENDIAN);

define alignment=2;

define space ran type=ram_space size=$(ADDRSIZE) default;
define space register type=register_space size=$(REGSIZE);

define register offset=0 size=$(REGSIZE) [
	r0 r1 r2 r3 r4
	r5 r6 r7 r8 r9
	r10 r11 r12 r13 r14
	r15 r16 r17 r18 r19
	r20 r21 r22 r23 r24
	r25 r26 r27 r28 r29
	r30 r31 r32 r33 r34
	r35 r236 r37 r38 r39
	r40 r41 r42 r43 r44
	r45 r46 r47 r48 r49
	r50 r51 r52 r53 sp
	lr r56 idn0 idn1 udn0
	udn1 udn2 udn3 zero
];

define token instr_bundle(64)
	mode = (62,63)
	
	# X1
	Opcode_X1 = (59,61)
	RRROpcodeExtension_X1 = (49,58)
	SrcB_X1 = (43,48)
	SrcA_X1 = (37,42)
	Dest_X1 = (31,36)
	Imm8OpcodeExtension_X1 = (51,58)
	Imm8_X1 = (43,50)
	MT_Imm14_X1_13_6 = (43,50)
	MT_Imm14_X1_5_0 = (31,36)
	MF_Imm14_X1 = (37,50)
	Imm16_X1 = (43,58)
	UnaryOpcodeExtension_X1 = (43,48)
	ShiftOpcodeExtension_X1 = (49,58)
	ShAmt_X1 = (43,48)
	BrType_X1 = (54,58)
	BrOff_X1_16_6 = (43,53)
	BrOff_X1_5_0 = (31,36)
	JumpOpcodeExtension_X1 = (58,58)
	JumpOff_X1 = (31,57)
	
	# X0
	Opcode_X0 = (28,30)
	RRROpcodeExtension_X0 = (18,27)
	SrcB_X0 = (12,17)
	SrcA_X0 = (6,11)
	Dest_X0 = (0,5)
	Imm8OpcodeExtension_X0 = (20,27)
	Imm8_X0 = (12,19)
	Imm16_X0 = (12,27)
	UnaryOpcodeExtension_X0 = (12,17)
	ShiftOpcodeExtension_X0 = (18,27)
	ShAmt_X0 = (12,17)
	BFOpcodeExtension_X0 = (24,27)
	BFStart_X0 = (18,23)
	BFEnd_X0 = (12,17)
	
	# Y2
	Opcode_Y2_1_1 = (57,57)
	SrcBDest_Y2 = (51,56)
	Opcode_Y2_0_0 = (26,26)
	SrcA_Y2 = (20,25)
	
	# Y1
	Opcode_Y1 = (58,61)
	RRROpcodeExtension_Y1 = (49,50)
	SrcB_Y1 = (43,48)
	SrcA_Y1 = (37,42)
	Dest_Y1 = (31,36)
	Imm8_Y1 = (43,50)
	UnaryOpcodeExtension_Y1 = (43,48)
	ShiftOpcodeExtension_Y1 = (49,50)
	ShAmt_Y1 = (43,48)
	
	# Y0
	Opcode_Y0 = (27,30)
	RRROpcodeExtension_Y0 = (18,19)
	SrcB_Y0 = (12,17)
	SrcA_Y0 = (6,11)
	Dest_Y0 = (0,5)
	Imm8_Y0 = (12,19)
	UnaryOpcodeExtension_Y0 = (12,17)
	ShiftOpcodeExtension_Y0 = (18,19)
	ShAmt_Y0 = (12,17)
	;

ISA Reference: tile-gx-instruction-set-architecture_compress.pdf

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:7 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
leyondleecommented, Jul 22, 2022

Thanks @emteere, I really appreciate your detailed explanation and examples.

The instruction strings are now displaying correctly 😃 afawetqt

0reactions
emteerecommented, Jul 19, 2022

I was able to get it to parse with only a few modifications.

        00012558 9d fd 6b                      move     r29,sp ; addxi r28, sp, 0xf8 ; st sp, lr
                 57 ce c6 
                 bf cb

The following is the first method. The second method I would use ONLY if you re-arranged the bytes for the Y0, Y1, Y2 the instructions could all be parsed with the same match pattern. It would save duplicating instruction match patterns and semantics only because the matching bits are in a different location in the instruction word. For example if you had an instruction like:

A C B B C A and if you could rearrange them during parse to: context: A A C B B C context: B B C x x C context C C x x x x

Each instruction parse would parse from the the first part of the context.

If they have the same bit pattern just re-arrange, then parsing from the context bits may be worth it. The same idea of the recursive parse is needed, it is a bit more complicated, and would also need to re-arrange the bytes for each parse phase as above.

@define ENDIAN "little"
@define REGSIZE "8"
@define ADDRSIZE "8"

define endian=$(ENDIAN);
define alignment=8;

define space ram type=ram_space size=$(ADDRSIZE) default;
define space register type=register_space size=$(REGSIZE);

define register offset=0 size=$(REGSIZE) [
	r0 r1 r2 r3 r4
	r5 r6 r7 r8 r9
	r10 r11 r12 r13 r14
	r15 r16 r17 r18 r19
	r20 r21 r22 r23 r24
	r25 r26 r27 r28 r29
	r30 r31 r32 r33 r34
	r35 r236 r37 r38 r39
	r40 r41 r42 r43 r44
	r45 r46 r47 r48 r49
	r50 r51 r52 r53 sp
	lr r56 idn0 idn1 udn0
	udn1 udn2 udn3 zero
];

define token instr_bundle(64)
	mode = (62,63)
	
	# X0
	Opcode_X0 = (28,30)
	RRROpcodeExtension_X0 = (18,27)
	SrcB_X0 = (12,17)
	SrcA_X0 = (6,11)
	Dest_X0 = (0,5)
	Imm8OpcodeExtension_X0 = (20,27)
	Imm8_X0 = (12,19)
	Imm16_X0 = (12,27)
	UnaryOpcodeExtension_X0 = (12,17)
	ShiftOpcodeExtension_X0 = (18,27)
	ShAmt_X0 = (12,17)
	BFOpcodeExtension_X0 = (24,27)
	BFStart_X0 = (18,23)
	BFEnd_X0 = (12,17)
	
	# X1
	Opcode_X1 = (59,61)
	RRROpcodeExtension_X1 = (49,58)
	SrcB_X1 = (43,48)
	SrcA_X1 = (37,42)
	Dest_X1 = (31,36)
	Imm8OpcodeExtension_X1 = (51,58)
	Imm8_X1 = (43,50)
	MT_Imm14_X1_13_6 = (43,50)
	MT_Imm14_X1_5_0 = (31,36)
	MF_Imm14_X1 = (37,50)
	Imm16_X1 = (43,58)
	UnaryOpcodeExtension_X1 = (43,48)
	ShiftOpcodeExtension_X1 = (49,58)
	ShAmt_X1 = (43,48)
	BrType_X1 = (54,58)
	BrOff_X1_16_6 = (43,53)
	BrOff_X1_5_0 = (31,36)
	JumpOpcodeExtension_X1 = (58,58)
	JumpOff_X1 = (31,57)
	
	# Y0
	Opcode_Y0 = (27,30)
	RRROpcodeExtension_Y0 = (18,19)
	SrcB_Y0 = (12,17)
	SrcA_Y0 = (6,11)
	Dest_Y0 = (0,5)
	Imm8_Y0 = (12,19)
	UnaryOpcodeExtension_Y0 = (12,17)
	ShiftOpcodeExtension_Y0 = (18,19)
	ShAmt_Y0 = (12,17)
	
	# Y1
	Opcode_Y1 = (58,61)
	RRROpcodeExtension_Y1 = (49,50)
	SrcB_Y1 = (43,48)
	SrcA_Y1 = (37,42)
	Dest_Y1 = (31,36)
	Imm8_Y1 = (43,50)
	UnaryOpcodeExtension_Y1 = (43,48)
	ShiftOpcodeExtension_Y1 = (49,50)
	ShAmt_Y1 = (43,48)
	
	# Y2
	Opcode_Y2_1_1 = (57,57)
	SrcBDest_Y2 = (51,56)
	Opcode_Y2_0_0 = (26,26)
	SrcA_Y2 = (20,25)
;

define register offset=0x1000 size=8 contextreg;
define context contextreg
	bundleType = (0,1)
	phase = (2,4)
;

attach variables [
	SrcA_X0 SrcB_X0 Dest_X0
	SrcA_X1 SrcB_X1 Dest_X1
	SrcA_Y0 SrcB_Y0 Dest_Y0
	SrcA_Y1 SrcB_Y1 Dest_Y1
	SrcA_Y2 SrcBDest_Y2
] [
	r0 r1 r2 r3 r4
	r5 r6 r7 r8 r9
	r10 r11 r12 r13 r14
	r15 r16 r17 r18 r19
	r20 r21 r22 r23 r24
	r25 r26 r27 r28 r29
	r30 r31 r32 r33 r34
	r35 r236 r37 r38 r39
	r40 r41 r42 r43 r44
	r45 r46 r47 r48 r49
	r50 r51 r52 r53 sp
	lr r56 idn0 idn1 udn0
	udn1 udn2 udn3 zero
];

:^instruction is phase=0 & bundleType=0 & mode=0x00 & instruction [ bundleType=1; phase=1; ] {}
:^instruction is phase=0 & bundleType=0 & mode!=0x00 & instruction [ bundleType=2; phase=1; ] {}

# sub constructor to move to the next instruction parse phase
EndPacket:"; "^instruction is phase=1 & instruction [ phase=2; ] { build instruction; }
EndPacket:"; "^instruction is phase=2 & instruction [ phase=3; ] { build instruction; }

# X Format
with : bundleType = 1 {
	:X is bundleType {} # Filler
}

# Y Format
with : bundleType = 2 {
	# Opcode_Y0 = (27,30), RRROpcodeExtension_Y0 = (18,19), SrcB_Y0 = (12,17), SrcA_Y0 = (6,11), Dest_Y0 = (0,5)
	:move Dest_Y0, SrcA_Y0 EndPacket is phase=1 & Opcode_Y0=0xA & RRROpcodeExtension_Y0=0x2 & SrcB_Y0=0x3F & SrcA_Y0 & Dest_Y0 & EndPacket {
		# do move
		build EndPacket;
	}
	
	# Opcode_Y1 = (58,61), Imm8_Y1 = (43,50), SrcA_Y1 = (37,42), Dest_Y1 = (31,36)
	:addxi Dest_Y1, SrcA_Y1, Imm8_Y1 EndPacket is phase=2 & Opcode_Y1=0x2 & Imm8_Y1 & SrcA_Y1 & Dest_Y1 & EndPacket {
		# do add
		build EndPacket;
	}
	
	# Opcode_Y2_1_1 = (57,57), SrcBDest_Y2 = (51,56), Opcode_Y2_0_0 = (26,26), SrcA_Y2 = (20,25)
	# don't need EndPacket as this is last instruction
	:st SrcA_Y2, SrcBDest_Y2 is phase=3 & Opcode_Y2_1_1=0x1 & SrcBDest_Y2 & Opcode_Y2_0_0=0x1 & SrcA_Y2 {
		# do store
	}
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

Sleigh Pcode: Read before write in instruction bundle #4581
I tried simplifying initTempRegisters() and saveTempRegisters() using a loop and accessing the registers through addresses. define space ...
Read more >
Specifying Representations of Machine Instructions
The SLED specification language is simple, and it is designed so that specifications can resemble instruction descriptions found in architecture manuals.
Read more >
ASSEMBLY INSTRUCTIONS USE AND CARE GUIDE ...
Read the entire manual prior to assembly and identify all the parts included in the package against the parts list. If any parts...
Read more >
SLEIGH COT BED WITH DRAWER
1) Insert the Barrel nut with the screwdriver slot at the bottom and ensure that it is aligned with the holes in the...
Read more >
LEGO Santa's Sleigh WITH FOUR REINDEER! - YouTube
Check out the brand new LEGO Santa's Sleigh set ! This amazing holiday set comes with FOUR REINDEER and is loaded full of...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found