Skip to content

Commit

Permalink
Extend #decode: to support decoding of multiple instructions
Browse files Browse the repository at this point in the history
This commit extends `AcProcessorDescription class >> #decode:` to
support decoding of multiple instructions from an byte array (for now
only for fixed-width instructions). This is useful to decode a chunk
of binary code at once.
  • Loading branch information
janvrany authored and shingarov committed Sep 4, 2024
1 parent 21f9fce commit 8825555
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 8 deletions.
14 changes: 10 additions & 4 deletions src/ArchC-Core/AcProcessorDescription.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,16 @@ AcProcessorDescription >> decodeBits: aBitVector [
AcProcessorDescription >> decodeableFormFor: code [
self hasConstantInstructionWidth ifTrue: [
(code isKindOf: ByteArray)"Sigh, Pharo has no #isByteArray"
ifTrue: [
code size == (self constantInstructionWidth // 8)
ifFalse: [ self error: 'Invalid bytes (too few or too much)' ].
^code toBitVectorEndian: self endian ].
ifTrue: [
| bitsPerInsn bytesPerInsn bvs |

bitsPerInsn := self constantInstructionWidth.
bytesPerInsn := bitsPerInsn // 8.
code size == bytesPerInsn
ifTrue: [ ^ code toBitVectorEndian: self endian ].
(code size \\ bytesPerInsn) ~~ 0
ifTrue: [ self error: 'Invalid bytes (too few or too much)' ].
^ (1 to: code size // bytesPerInsn) collect: [ :i | code toBitVector: bitsPerInsn endian: self endian startingAt: (i - 1) * bytesPerInsn + 1 ]].
(code isCollection and:[code isSequenceable])
ifTrue:[ ^code ].
^code toBitVector: self constantInstructionWidth
Expand Down
22 changes: 18 additions & 4 deletions src/ArchC-Core/ByteArray.extension.st
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
Extension { #name : #ByteArray }

{ #category : #'*ArchC-Core' }
ByteArray >> toBitVectorEndian: endian [
self assert: self size isPowerOfTwo.
ByteArray >> toBitVector: xlen endian: endian startingAt: startIndex [
self assert: (xlen \\ 8) == 0.
self assert: (xlen // 8) isPowerOfTwo.

endian ifBig: [
^ (BitVector concatAll: (self collect: [ :aByte | aByte toBitVector: 8] as: Array)) simplify
^ (BitVector concatAll: ((startIndex to: startIndex + (xlen // 8) - 1 by: 1) collect: [ :i | (self at:i) toBitVector: 8] as: Array)) simplify
] ifLittle: [
^ (BitVector concatAll: (self reverse collect: [ :aByte | aByte toBitVector: 8] as: Array)) simplify
^ (BitVector concatAll: ((startIndex + (xlen // 8) - 1 to: startIndex by: -1) collect: [ :i | (self at:i) toBitVector: 8] as: Array)) simplify
].

"
#[ 16r0A 16r0B 16r0C 16r0D ] toBitVector: 32 endian: Endian little startingAt: 1
#[ 16r0A 16r0B 16r0C 16r0D ] toBitVector: 32 endian: Endian big startingAt: 1
"

"Created: / 18-06-2024 / 22:32:07 / Jan Vrany <jan.vrany@labware.com>"
]

{ #category : #'*ArchC-Core' }
ByteArray >> toBitVectorEndian: endian [
^ self toBitVector: self size * 8 endian: endian startingAt: 1

"
#[ 16r0A 16r0B 16r0C 16r0D ] toBitVectorEndian: Endian little.
#[ 16r0A 16r0B 16r0C 16r0D ] toBitVectorEndian: Endian big.
Expand Down

0 comments on commit 8825555

Please sign in to comment.