VM Maker: VMMaker.oscog-lw.207.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

VM Maker: VMMaker.oscog-lw.207.mcz

commits-2
 
Lars Wassermann uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker.oscog-lw.207.mcz

==================== Summary ====================

Name: VMMaker.oscog-lw.207
Author: lw
Time: 24 August 2012, 8:15:36.393 pm
UUID: 052f916f-09bd-754b-80f8-2473b0654afb
Ancestors: VMMaker.oscog-eem.206

- added a class comment to the ARMCompiler

- added CArg0Reg-CArg3Reg register numbers to ARMCompiler class.

- moved Temp, Class, Result and RISCTempReg from r0-r3 to r7-r10, because then we don't have to save them when calling back to the Interpreter (they are callee saved). Subsequently, we needed to update the tests.

- Reimplemented genPassConst and genPassReg to reflect the correct ARM ABI, and not IA32 ABI.

=============== Diff against VMMaker.oscog-eem.206 ===============

Item was changed:
  CogAbstractInstruction subclass: #CogARMCompiler
  instanceVariableNames: ''
+ classVariableNames: 'AL CArg0Reg CArg1Reg CArg2Reg CArg3Reg CC CS EQ GE GT HI LDMFD LE LR LS LT MI NE PC PL R0 R1 R10 R11 R12 R2 R3 R4 R5 R6 R7 R8 R9 RISCTempReg SP STMFD VC VS'
- classVariableNames: 'AL CC CS EQ GE GT HI LDMFD LE LR LS LT MI NE PC PL R0 R1 R10 R11 R12 R2 R3 R4 R5 R6 R7 R8 R9 RISCTempReg SP STMFD VC VS'
  poolDictionaries: ''
  category: 'VMMaker-JIT'!
+
+ !CogARMCompiler commentStamp: 'lw 8/23/2012 19:38' prior: 0!
+ I generate ARM instructions from CogAbstractInstructions.  For reference see
+ http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.set.architecture/index.html
+
+ The Architecture Reference Manual used is that of version 5, which includes some version 6 instructions. Of those, only pld is used(for PrefetchAw).
+
+ This class does not take any special action to flush the instruction cache on instruction-modification.!

Item was changed:
  ----- Method: CogARMCompiler class>>initialize (in category 'class initialization') -----
  initialize
 
  "Initialize various ARM instruction-related constants."
  "CogARMCompiler initialize"
 
  | specificOpcodes refs conditionCodes |
  super initialize.
  self ~~ CogARMCompiler ifTrue: [^self].
 
  R0 := 0. R1 := 1.
  R2 := 2. R3 := 3.
  R4 := 4. R5 := 5.
  R6 := 6. R7 := 7.
  R8 := 8. R9 := 9.
  R10 := 10. R11 := 11.
  R12 := 12.
  SP := 13.
  LR := 14.
  PC := 15.
 
+ CArg0Reg := 0. CArg1Reg := 1. CArg2Reg := 2. CArg3Reg := 3.
- RISCTempReg := R3.
 
+ RISCTempReg := R10.
+
  "Condition Codes"
  conditionCodes := #(EQ NE CS CC MI PL VS VC HI LS GE LT GT LE AL).
  conditionCodes withIndexDo: [ :classVarName :value |
  self classPool
  declare: classVarName from: Undeclared;
  at: classVarName put: value - 1].
 
  "Specific instructions"
  LastRTLCode isNil ifTrue:
  [CogRTLOpcodes initialize].
  specificOpcodes := #(LDMFD STMFD).
  refs := (thisContext method literals select: [:l| l isVariableBinding and: [classPool includesKey: l key]]) collect:
  [:ea| ea key].
  (classPool keys reject: [:k| (specificOpcodes includes: k) or: [refs includes: k] or: [conditionCodes includes: k]]) do:
  [:k|
  Undeclared declare: k from: classPool].
  specificOpcodes withIndexDo:
  [:classVarName :value|
  self classPool
  declare: classVarName from: Undeclared;
  at: classVarName put: value + LastRTLCode - 1]!

Item was changed:
  ----- Method: CogARMCompiler>>cResultRegister (in category 'abi') -----
  cResultRegister
  "Answer the abstract register for the C result register.
  Only partially implemented.  Works on x86 since TempReg = EAX = C result reg."
+ ^R0!
- ^self abstractRegisterForConcreteRegister: R0!

Item was changed:
  ----- Method: CogARMCompiler>>concreteRegister: (in category 'encoding') -----
  concreteRegister: registerIndex
  "Map a possibly abstract register into a concrete one.  Abstract registers
   (defined in CogAbstractOpcodes) are all negative.  If registerIndex is
  negative assume it is an abstract register."
 
  "N.B. According to BSABI, R0-R3 are caller-save, R4-R12 are callee save.
+ Note that R9 might be a special register for the implementation. In some slides it is refered to as sb. R10 can contain the stack limit (sl), R11 the fp. R12 is an intra-procedure scratch instruction pointer for link purposes. It can also be used.
+ R10 is used as temporary inside a single abstract opcode implementation"
+ "R0-R3 are used when calling back to the interpreter. Using them would require saving and restoring their values, so they are omitted so far. R12 is the only unused register at the moment.."
- Note that R9 might be a special register for the implementation. In some slides it is refered to as sb. R10 contains the stack limit (sl), R11 the fp. R12 is an intra-procedure scratch instruction pointer for link purposes.
- R3 is used as temporary inside a single abstract opcode implementation"
-
  ^registerIndex
  caseOf: {
+ [TempReg] -> [R7].
+ [ClassReg] -> [R8].
+ [ReceiverResultReg] -> [R9].
- [TempReg] -> [R0].
- [ClassReg] -> [R1].
- [ReceiverResultReg] -> [R2].
  [SendNumArgsReg] -> [R6].
  [SPReg] -> [SP].
  [FPReg] -> [R11].
  [Arg0Reg] -> [R4].
  [Arg1Reg] -> [R5] }
  otherwise:
  [self assert: (registerIndex between: R0 and: PC).
  registerIndex]!

Item was changed:
  ----- Method: CogARMCompiler>>genPassConst:asArgument: (in category 'abi') -----
  genPassConst: constant asArgument: zeroRelativeArgIndex
+ zeroRelativeArgIndex caseOf: {
+ [0] -> [cogit MoveCq: constant R: CArg0Reg].
+ [1] -> [cogit MoveCq: constant R: CArg1Reg].
+ [2] -> [cogit MoveCq: constant R: CArg2Reg].
+ [3] -> [cogit MoveCq: constant R: CArg3Reg].}.
- cogit
- MoveCq: constant R: TempReg;
- PushR: TempReg.
  ^0!

Item was changed:
  ----- Method: CogARMCompiler>>genPassReg:asArgument: (in category 'abi') -----
  genPassReg: abstractRegister asArgument: zeroRelativeArgIndex
+ zeroRelativeArgIndex caseOf: {
+ [0] -> [cogit MoveR: abstractRegister R: CArg0Reg].
+ [1] -> [cogit MoveR: abstractRegister R: CArg1Reg].
+ [2] -> [cogit MoveR: abstractRegister R: CArg2Reg].
+ [3] -> [cogit MoveR: abstractRegister R: CArg3Reg].}.
- cogit PushR: abstractRegister.
  ^0!

Item was changed:
  ----- Method: CogARMCompiler>>genRestoreRegisters (in category 'abi') -----
  genRestoreRegisters
  "Load the general purpose registers after the return of a trampoline call."
+ "Because no registers were saved we don't restore any."
+ "cogit
+ gen: LDMFD operand: 16r7F"!
- "Load r0-r6, all of which were saved. Don't load sb(r9), sl(r10), fp(r11), sp or lr"
- cogit
- gen: LDMFD operand: 16r7F!

Item was changed:
  ----- Method: CogARMCompiler>>genSaveRegisters (in category 'abi') -----
  genSaveRegisters
  "Save the general purpose registers for a trampoline call."
+ "Save none, because we use only callee saved registers."
+ "cogit
+ gen: STMFD operand: 16r7F"!
- "Save r0-r6, all of which are used for variables. Don't save sb(r9), sl(r10), fp(r11), sp or lr"
- cogit
- gen: STMFD operand: 16r7F!

Item was changed:
  ----- Method: CogARMCompilerForTests class>>dataRegistersWithAccessorsDo: (in category 'test support') -----
  dataRegistersWithAccessorsDo: aTrinaryBlock
  "r0 ... sp. We can't use pc or RISCTempReg, because some opcodes may be encoded as multiple instructions and this, we need to be able to step."
+ #(0 1 2 3 4 5 6 7 8 9 11 12 13 14) withIndexDo:
- #(0 1 2 4 5 6 7 8 9 10 11 12 13 14) withIndexDo:
  [:reg :i|
  aTrinaryBlock
  value: reg
+ value: (#(r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r11 r12 sp lr) at: i)
+ value: (#(r0: r1: r2: r3: r4: r5: r6: r7: r8: r9: r11: r12: sp: lr:) at: i)]!
- value: (#(r0 r1 r2 r4 r5 r6 r7 r8 r9 r10 r11 r12 sp lr) at: i)
- value: (#(r0: r1: r2: r4: r5: r6: r7: r8: r9: r10: r11: r12: sp: lr:) at: i)]!

Item was changed:
  ----- Method: CogARMCompilerTests>>testAdd (in category 'tests') -----
  testAdd
  "self new testAdd"
 
  "the forms are valid, "
  "test AddCqR"
  self concreteCompilerClass registersWithNamesDo: [ :reg :regName |
  #(0 16rF 16rFF) do:
  [:n| | inst len |
  inst := self gen: AddCqR operand: n operand: reg.
  len := inst concretizeAt: 0.
  self processor
  disassembleInstructionAt: 0
  In: inst machineCode object
  into: [:str :sz| | plainJane herIntended |
  plainJane := self strip: str.
  herIntended := 'adds ', regName, ', ', regName, ', #', n asString.
  self assert: (plainJane match: herIntended)]]].
 
  "test AddCwR"
  self concreteCompilerClass registersWithNamesDo: [ :reg :regName |
  #(16rFFFFFFFF 16r88888888 0) do:
  [:n| | inst len |
  inst := self gen: AddCwR operand: n operand: reg.
  len := inst concretizeAt: 0.
  self processor
  disassembleInstructionAt: 0
  In: inst machineCode object
  into: [:str :sz| | plainJane herIntended |
  plainJane := self strip: str.
+ herIntended := 'mov sl, #', (n bitAnd: 16rFF << 8) asString.
- herIntended := 'mov r3, #', (n bitAnd: 16rFF << 8) asString.
  self assert: (plainJane match: herIntended)].
  self processor
  disassembleInstructionAt: 4
  In: inst machineCode object
  into: [:str :sz| | plainJane herIntended |
  plainJane := self strip: str.
+ herIntended := 'orr sl, sl, #', (n bitAnd: 16rFF << 16) asString.
- herIntended := 'orr r3, r3, #', (n bitAnd: 16rFF << 16) asString.
  self assert: (plainJane match: herIntended)].
  self processor
  disassembleInstructionAt: 8
  In: inst machineCode object
  into: [:str :sz| | plainJane herIntended |
  plainJane := self strip: str.
+ herIntended := 'orr sl, sl, #', (n bitAnd: 16rFF << 24) signedIntFromLong asString.
- herIntended := 'orr r3, r3, #', (n bitAnd: 16rFF << 24) signedIntFromLong asString.
  self assert: (plainJane match: herIntended)].
  self processor
  disassembleInstructionAt: 12
  In: inst machineCode object
  into: [:str :sz| | plainJane herIntended |
  plainJane := self strip: str.
+ herIntended := 'orr sl, sl, #', (n bitAnd: 16rFF) asString.
- herIntended := 'orr r3, r3, #', (n bitAnd: 16rFF) asString.
  self assert: (plainJane match: herIntended)].
  self processor
  disassembleInstructionAt: 16
  In: inst machineCode object
  into: [:str :sz| | plainJane herIntended |
  plainJane := self strip: str.
+ herIntended := 'adds ', regName, ', ', regName, ', sl'.
- herIntended := 'adds ', regName, ', ', regName, ', r3'.
  self assert: (plainJane match: herIntended)]]]
  !

Item was changed:
  ----- Method: CogARMCompilerTests>>testPrefetchAw (in category 'tests') -----
  testPrefetchAw
  "self new testPrefetchAw"
 
  #(16rFF00FF00 16r00000012) do:
  [:n| | inst len |
  inst := self gen: PrefetchAw operand: n.
  len := inst concretizeAt: 0.
  self processor
  disassembleInstructionAt: 12
  In: inst machineCode object
  into: [:str :sz| | plainJane herIntended |
  "Convert e.g. '00000000: movl %eax, 0x2(%eax) : 89 40 02' to  'movl %eax, 0x2(%eax)'"
  plainJane := self strip: str.
+ herIntended := 'pld [sl', ((n bitAnd: 16rFF) = 0 ifTrue: [''] ifFalse: [', #', (n bitAnd: 16rFF) asString]) ,']'.
- herIntended := 'pld [r3', ((n bitAnd: 16rFF) = 0 ifTrue: [''] ifFalse: [', #', (n bitAnd: 16rFF) asString]) ,']'.
  self assert: (plainJane match: herIntended).
  self assert: len = 16]].
  !

Item was changed:
  ----- Method: CogAbstractInstruction>>abstractRegisterForConcreteRegister: (in category 'private') -----
  abstractRegisterForConcreteRegister: reg
  (self concreteRegister: TempReg) = reg ifTrue: [^TempReg].
  (self concreteRegister: ReceiverResultReg) = reg ifTrue: [^ReceiverResultReg].
  (self concreteRegister: ClassReg) = reg ifTrue: [^ClassReg].
  (self concreteRegister: SendNumArgsReg) = reg ifTrue: [^SendNumArgsReg].
  (self concreteRegister: Arg0Reg) = reg ifTrue: [^Arg0Reg].
  (self concreteRegister: Arg1Reg) = reg ifTrue: [^Arg1Reg].
  (self concreteRegister: FPReg) = reg ifTrue: [^FPReg].
  (self concreteRegister: SPReg) = reg ifTrue: [^SPReg].
  self error: 'could not find abstract register'.
  ^0
 
+ "While the below works fine in Smalltalk it of course doesn't work in C ;)"
- "While the below works fine in Smalltalk it fo course doesn't work in C ;)"
 
  "^reg caseOf: {
  [self concreteRegister: TempReg] -> [TempReg].
  [self concreteRegister: ReceiverResultReg] -> [ReceiverResultReg].
  [self concreteRegister: ClassReg] -> [ClassReg].
  [self concreteRegister: SendNumArgsReg] -> [SendNumArgsReg].
  [self concreteRegister: Arg0Reg] -> [Arg0Reg].
  [self concreteRegister: Arg1Reg] -> [Arg1Reg].
  [self concreteRegister: FPReg] -> [FPReg].
  [self concreteRegister: SPReg] -> [SPReg] }"!