diff --git a/src/ArchC-Core-Tests/AcAssemblerTest.class.st b/src/ArchC-Core-Tests/AcAssemblerTest.class.st index 54e4aed..a5118a0 100644 --- a/src/ArchC-Core-Tests/AcAssemblerTest.class.st +++ b/src/ArchC-Core-Tests/AcAssemblerTest.class.st @@ -320,7 +320,7 @@ AcAssemblerTest >> test_byte [ result := AcProcessorDescriptions powerpc assembler parse: '.byte 0x7F'. self assert: result binaryEncoding equals: 16r7F. - self assert: result disassemble equals: '.byte 0x' , (16r7F printStringRadix: 16). + self assert: result disassemble equals: '.byte 0x7F'. ] { #category : #data } @@ -329,7 +329,7 @@ AcAssemblerTest >> test_u16 [ result := AcProcessorDescriptions powerpc assembler parse: '.2byte 0x7FE0'. self assert: result binaryEncoding equals: 16r7FE0. - self assert: result disassemble equals: '.2byte 0x' , (16r7FE0 printStringRadix:16). + self assert: result disassemble equals: '.2byte 0x7FE0'. ] { #category : #data } @@ -338,7 +338,7 @@ AcAssemblerTest >> test_u32 [ result := AcProcessorDescriptions powerpc assembler parse: '.4byte 0x7FE00008'. self assert: result binaryEncoding equals: 16r7FE00008. - self assert: result disassemble equals: '.4byte 0x' , (16r7FE00008 printStringRadix:16). + self assert: result disassemble equals: '.4byte 0x7FE00008'. ] { #category : #data } @@ -347,5 +347,5 @@ AcAssemblerTest >> test_u64 [ result := AcProcessorDescriptions powerpc assembler parse: '.8byte 0x7FE00008CAFEAFFE'. self assert: result binaryEncoding equals: 16r7FE00008CAFEAFFE. - self assert: result disassemble equals: '.8byte 0x' , (16r7FE00008CAFEAFFE printStringRadix:16). + self assert: result disassemble equals: '.8byte 0x7FE00008CAFEAFFE'. ] diff --git a/src/ArchC-Core/AcAsmOperandModifier.class.st b/src/ArchC-Core/AcAsmOperandModifier.class.st index aebbbfd..7eaa8d3 100644 --- a/src/ArchC-Core/AcAsmOperandModifier.class.st +++ b/src/ArchC-Core/AcAsmOperandModifier.class.st @@ -82,6 +82,11 @@ AcAsmOperandModifier >> encodeInFields: fs accordingTo: format [ self subclassResponsibility ] +{ #category : #testing } +AcAsmOperandModifier >> isAcAsmOperandModifier [ + ^ true +] + { #category : #queries } AcAsmOperandModifier >> isPRREL [ ^ self class isPCREL diff --git a/src/ArchC-Core/AcAsmSyntax.class.st b/src/ArchC-Core/AcAsmSyntax.class.st index 80616f8..0406b58 100644 --- a/src/ArchC-Core/AcAsmSyntax.class.st +++ b/src/ArchC-Core/AcAsmSyntax.class.st @@ -35,9 +35,9 @@ AcAsmSyntax >> assembler [ allOperands := actualOperands copy addAll: constraints; yourself. fieldValues := Dictionary new. allOperands keysAndValuesDo: [ :opDef :v | - fieldValues addAll: (opDef asOperandInstantiation encodeValue: v accoringTo: instruction format) ]. + fieldValues addAll: (opDef asOperandInstantiation encodeValue: v + accordingTo: instruction format) ]. self instruction inEnvironment: fieldValues ] - ] { #category : #accessing } diff --git a/src/ArchC-Core/AcInt.class.st b/src/ArchC-Core/AcInt.class.st index 996a304..389abe2 100644 --- a/src/ArchC-Core/AcInt.class.st +++ b/src/ArchC-Core/AcInt.class.st @@ -35,7 +35,20 @@ AcInt >> assembler [ { #category : #'encoding / decoding' } AcInt >> disassemble [ - ^ self name , ' 0x' , (self value printStringRadix: 16) + binaryEncoding isSymbolic ifTrue: [ + | variables | + + variables := binaryEncoding variableNames. + variables size == 1 ifTrue: [ + "Simple function of one variable" + ^ self name , ' {' , variables anyOne , '}' + ] ifFalse: [ + "Function of multiple variables, print the whole AST" + ^ self name , ' {' , binaryEncoding astToString , '}' + ]. + ] ifFalse: [ + ^ self name , ' 0x', (self value printPaddedWith:$0 to: self bitWidth // 8 base:16) + ]. ] { #category : #'encoding / decoding' } diff --git a/src/ArchC-Core/AcProcessorDescription.class.st b/src/ArchC-Core/AcProcessorDescription.class.st index b1245a5..f29d4e8 100644 --- a/src/ArchC-Core/AcProcessorDescription.class.st +++ b/src/ArchC-Core/AcProcessorDescription.class.st @@ -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 diff --git a/src/ArchC-Core/AsmOperandInstantiation.class.st b/src/ArchC-Core/AsmOperandInstantiation.class.st index 97ed3fa..bc80d32 100644 --- a/src/ArchC-Core/AsmOperandInstantiation.class.st +++ b/src/ArchC-Core/AsmOperandInstantiation.class.st @@ -86,10 +86,12 @@ AsmOperandInstantiation >> encodeSimpleValue: value [ ] { #category : #private } -AsmOperandInstantiation >> encodeValue: value accoringTo: format [ - (value isKindOf: AcAsmOperandModifier) ifTrue: [ ^value encodeInFields: self accordingTo: format ]. - ^self encodeSimpleValue: value - +AsmOperandInstantiation >> encodeValue: value accordingTo: format [ + value isAcAsmOperandModifier ifTrue: [ + ^ value encodeInFields: self accordingTo: format + ] ifFalse: [ + ^ self encodeSimpleValue: value + ] ] { #category : #rewriting } diff --git a/src/ArchC-Core/ByteArray.extension.st b/src/ArchC-Core/ByteArray.extension.st index 5e4b9b2..385e14e 100644 --- a/src/ArchC-Core/ByteArray.extension.st +++ b/src/ArchC-Core/ByteArray.extension.st @@ -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 " +] + +{ #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. diff --git a/src/ArchC-Core/Object.extension.st b/src/ArchC-Core/Object.extension.st index c3ef449..bbcd62c 100644 --- a/src/ArchC-Core/Object.extension.st +++ b/src/ArchC-Core/Object.extension.st @@ -4,3 +4,8 @@ Extension { #name : #Object } Object >> decodeFor: anISA [ ^(anISA decodeableFormFor: self) decodeFor: anISA ] + +{ #category : #'*ArchC-Core' } +Object >> isAcAsmOperandModifier [ + ^ false +] diff --git a/src/ArchC-Core/ProcessorInstructionDeclaration.class.st b/src/ArchC-Core/ProcessorInstructionDeclaration.class.st index e38c8da..9764e50 100644 --- a/src/ArchC-Core/ProcessorInstructionDeclaration.class.st +++ b/src/ArchC-Core/ProcessorInstructionDeclaration.class.st @@ -12,7 +12,8 @@ Class { 'format', 'internalBindings', 'syntax', - 'isa' + 'isa', + 'binaryEncoding' ], #classVars : [ 'EmptyBindings' @@ -132,7 +133,10 @@ ProcessorInstructionDeclaration >> assertInvariants [ { #category : #accessing } ProcessorInstructionDeclaration >> binaryEncoding [ - ^format binaryEncoding inEnvironment: internalBindings + binaryEncoding isNil ifTrue: [ + binaryEncoding := format binaryEncoding inEnvironment: internalBindings. + ]. + ^ binaryEncoding ] { #category : #accessing } diff --git a/src/ArchC-DSL/AcAsmSyntax.extension.st b/src/ArchC-DSL/AcAsmSyntax.extension.st index 66a1c05..3294d92 100644 --- a/src/ArchC-DSL/AcAsmSyntax.extension.st +++ b/src/ArchC-DSL/AcAsmSyntax.extension.st @@ -16,7 +16,8 @@ AcAsmSyntax >> assembleDSL: mnemonic operands: operandList [ | operandDef | operandDef := self operands at: operandIdx. - environment addAll: (operandDef asOperandInstantiation encodeValue: operandValue accoringTo: instruction format). + environment addAll: (operandDef asOperandInstantiation encodeValue: operandValue + accordingTo: instruction format). operandIdx := operandIdx + 1. ]. ]. @@ -36,9 +37,9 @@ AcAsmSyntax >> assembleDSL: mnemonic operands: operandList [ baseMod := operandFormat base modifier. environment addAll: (offsetDef asOperandInstantiation encodeValue: (offsetMod new x: operandValue offset) - accoringTo: instruction format). + accordingTo: instruction format). environment addAll: (baseDef asOperandInstantiation encodeValue: (baseMod new x: operandValue base) - accoringTo: instruction format). + accordingTo: instruction format). operandIdx := operandIdx + 2. ] ifFalse: [ @@ -48,7 +49,7 @@ AcAsmSyntax >> assembleDSL: mnemonic operands: operandList [ operandModifier := operandFormat modifier. environment addAll: (operandDef asOperandInstantiation encodeValue: (operandModifier new x: operandValue) - accoringTo: instruction format). + accordingTo: instruction format). operandIdx := operandIdx + 1. ]. @@ -57,7 +58,7 @@ AcAsmSyntax >> assembleDSL: mnemonic operands: operandList [ self constraints keysAndValuesDo: [:operandDef :operand | environment addAll: (operandDef asOperandInstantiation encodeValue: operand - accoringTo: instruction format) + accordingTo: instruction format) ]. ^self instruction inEnvironment: environment ]