DIRECTORY TargetArchitecture, MIPSArchitecture, RuntimeError; MIPSArchitectureImpl: CEDAR PROGRAM IMPORTS TargetArchitecture, MIPSArchitecture, RuntimeError EXPORTS MIPSArchitecture ~ { Noop: PUBLIC PROCEDURE [] RETURNS [MIPSArchitecture.MIPSInstruction] ~ { formatR: MIPSArchitecture.FormatR ~ [ op: MIPSArchitecture.Op.special, rs: MIPSArchitecture.zero, rt: MIPSArchitecture.zero, rd: MIPSArchitecture.zero, sa: 0, opspecial: MIPSArchitecture.OpSpecial.sll]; instruction: MIPSArchitecture.MIPSInstruction ~ LOOPHOLE[formatR]; RETURN [instruction]; }; LW: PUBLIC PROCEDURE [ base: MIPSArchitecture.Register, offset: MIPSArchitecture.Simm16, dest: MIPSArchitecture.Register] RETURNS [MIPSArchitecture.MIPSInstruction] ~ { formatSI: MIPSArchitecture.FormatSI ~ [ op: MIPSArchitecture.Op.lw, rs: base, rt: dest, simm16: offset]; instruction: MIPSArchitecture.MIPSInstruction ~ LOOPHOLE[formatSI]; RETURN [instruction]; }; SW: PUBLIC PROCEDURE [ source: MIPSArchitecture.Register, base: MIPSArchitecture.Register, offset: MIPSArchitecture.Simm16] RETURNS [MIPSArchitecture.MIPSInstruction] ~ { formatSI: MIPSArchitecture.FormatSI ~ [ op: MIPSArchitecture.Op.sw, rs: base, rt: source, simm16: offset]; instruction: MIPSArchitecture.MIPSInstruction ~ LOOPHOLE[formatSI]; RETURN [instruction]; }; LUI: PUBLIC PROCEDURE [ hi: MIPSArchitecture.Imm16, dest: MIPSArchitecture.Register] RETURNS [MIPSArchitecture.MIPSInstruction] ~ { formatI: MIPSArchitecture.FormatI ~ [ op: MIPSArchitecture.Op.lui, rs: dest, rt: dest, imm16: hi]; instruction: MIPSArchitecture.MIPSInstruction ~ LOOPHOLE[formatI]; RETURN [instruction]; }; ORI: PUBLIC PROCEDURE [ source: MIPSArchitecture.Register, constant: MIPSArchitecture.Imm16, dest: MIPSArchitecture.Register] RETURNS [MIPSArchitecture.MIPSInstruction] ~ { formatI: MIPSArchitecture.FormatI ~ [ op: MIPSArchitecture.Op.ori, rs: source, rt: dest, imm16: constant]; instruction: MIPSArchitecture.MIPSInstruction ~ LOOPHOLE[formatI]; RETURN [instruction]; }; ADDIU: PUBLIC PROCEDURE [ source: MIPSArchitecture.Register, constant: MIPSArchitecture.Simm16, dest: MIPSArchitecture.Register] RETURNS [MIPSArchitecture.MIPSInstruction] ~ { formatSI: MIPSArchitecture.FormatSI ~ [ op: MIPSArchitecture.Op.addiu, rs: source, rt: dest, simm16: constant]; instruction: MIPSArchitecture.MIPSInstruction ~ LOOPHOLE[formatSI]; RETURN [instruction]; }; J: PUBLIC PROCEDURE [ pc: MIPSArchitecture.MIPSAddress, to: MIPSArchitecture.MIPSAddress] RETURNS [MIPSArchitecture.MIPSInstruction] ~ { nextPC: MIPSArchitecture.MIPSAddress ~ MIPSArchitecture.NextMIPSInstruction[pc: pc]; nextPCHighOrderBits: MIPSArchitecture.HighOrderBits ~ MIPSArchitecture.GetHighOrderBits[address: nextPC]; toHighOrderBits: MIPSArchitecture.HighOrderBits ~ MIPSArchitecture.GetHighOrderBits[address: to]; disp26: MIPSArchitecture.Disp26 ~ MIPSArchitecture.GetTargetBits[address: to]; formatJ: MIPSArchitecture.FormatJ ~ [ op: MIPSArchitecture.Op.j, disp26: disp26]; instruction: MIPSArchitecture.MIPSInstruction ~ LOOPHOLE[formatJ]; IF pc.IsNullMIPSAddress[] THEN { ERROR MIPSArchitecture.NullMIPSAddress; }; IF to.IsNullMIPSAddress[] THEN { ERROR MIPSArchitecture.NullMIPSAddress; }; IF nextPCHighOrderBits # toHighOrderBits THEN { ERROR MIPSArchitecture.CantReach; }; RETURN [instruction]; }; JAL: PUBLIC PROCEDURE [ pc: MIPSArchitecture.MIPSAddress, to: MIPSArchitecture.MIPSAddress] RETURNS [MIPSArchitecture.MIPSInstruction] ~ { nextPC: MIPSArchitecture.MIPSAddress ~ MIPSArchitecture.NextMIPSInstruction[pc: pc]; nextPCHighOrderBits: MIPSArchitecture.HighOrderBits ~ MIPSArchitecture.GetHighOrderBits[address: nextPC]; toHighOrderBits: MIPSArchitecture.HighOrderBits ~ MIPSArchitecture.GetHighOrderBits[address: to]; disp26: MIPSArchitecture.Disp26 ~ MIPSArchitecture.GetTargetBits[address: to]; formatJ: MIPSArchitecture.FormatJ ~ [ op: MIPSArchitecture.Op.jal, disp26: disp26]; instruction: MIPSArchitecture.MIPSInstruction ~ LOOPHOLE[formatJ]; IF pc.IsNullMIPSAddress[] THEN { ERROR MIPSArchitecture.NullMIPSAddress; }; IF to.IsNullMIPSAddress[] THEN { ERROR MIPSArchitecture.NullMIPSAddress; }; IF nextPCHighOrderBits # toHighOrderBits THEN { ERROR MIPSArchitecture.CantReach; }; RETURN [instruction]; }; JR: PUBLIC PROCEDURE [to: MIPSArchitecture.Register] RETURNS [MIPSArchitecture.MIPSInstruction] ~ { formatR: MIPSArchitecture.FormatR ~ [ op: MIPSArchitecture.Op.special, rs: to, rt: MIPSArchitecture.zero, rd: MIPSArchitecture.zero, sa: 0, opspecial: MIPSArchitecture.OpSpecial.jr]; instruction: MIPSArchitecture.MIPSInstruction ~ LOOPHOLE[formatR]; RETURN [instruction]; }; JALR: PUBLIC PROCEDURE [ returnAddress: MIPSArchitecture.Register _ MIPSArchitecture.ra, to: MIPSArchitecture.Register] RETURNS [MIPSArchitecture.MIPSInstruction] ~ { formatR: MIPSArchitecture.FormatR ~ [ op: MIPSArchitecture.Op.special, rs: to, rt: MIPSArchitecture.zero, rd: returnAddress, sa: 0, opspecial: MIPSArchitecture.OpSpecial.jalr]; instruction: MIPSArchitecture.MIPSInstruction ~ LOOPHOLE[formatR]; RETURN [instruction]; }; RelocateBranch: PROCEDURE [ instruction: MIPSArchitecture.MIPSInstruction, from: MIPSArchitecture.MIPSAddress, to: MIPSArchitecture.MIPSAddress] RETURNS [MIPSArchitecture.MIPSInstruction] ~ { relocated: MIPSArchitecture.MIPSInstruction _ instruction; instructionDisp16: MIPSArchitecture.Disp16 ~ instruction.GetDisp16[]; displacement: TargetArchitecture.Displacement ~ instructionDisp16 * BYTES[MIPSArchitecture.MIPSInstruction]; targetAddress: MIPSArchitecture.MIPSAddress ~ MIPSArchitecture.MIPSAddressFromDisplacement[from, displacement]; relocationDisplacement: TargetArchitecture.Displacement ~ MIPSArchitecture.DisplacementFromMIPSAddresses[here: to, there: targetAddress]; relocationDisp16: MIPSArchitecture.Disp16 ~ relocationDisplacement / BYTES[MIPSArchitecture.MIPSInstruction]; IF relocationDisp16 NOT IN [MIPSArchitecture.firstDisp16..MIPSArchitecture.lastDisp16] THEN { ERROR MIPSArchitecture.CantRelocate; }; IF relocationDisplacement MOD BYTES[MIPSArchitecture.MIPSInstruction] # 0 THEN { ERROR MIPSArchitecture.CantRelocate; }; relocated _ instruction.SetDisp16[disp16: relocationDisp16]; RETURN [relocated]; }; RelocateFormatJ: PROCEDURE [ instruction: MIPSArchitecture.MIPSInstruction, from: MIPSArchitecture.MIPSAddress, to: MIPSArchitecture.MIPSAddress] RETURNS [MIPSArchitecture.MIPSInstruction] ~ { nextFrom: MIPSArchitecture.MIPSAddress ~ MIPSArchitecture.NextMIPSInstruction[pc: from]; nextTo: MIPSArchitecture.MIPSAddress ~ MIPSArchitecture.NextMIPSInstruction[pc: to]; fromHighOrderBits: MIPSArchitecture.HighOrderBits ~ MIPSArchitecture.GetHighOrderBits[address: nextFrom]; toHighOrderBits: MIPSArchitecture.HighOrderBits ~ MIPSArchitecture.GetHighOrderBits[address: nextTo]; IF fromHighOrderBits # toHighOrderBits THEN { ERROR MIPSArchitecture.CantRelocate; }; RETURN [instruction]; }; Relocate: PUBLIC PROCEDURE [ instruction: MIPSArchitecture.MIPSInstruction, from: MIPSArchitecture.MIPSAddress, to: MIPSArchitecture.MIPSAddress] RETURNS [MIPSArchitecture.MIPSInstruction] ~ { relocated: MIPSArchitecture.MIPSInstruction _ instruction; IF instruction.IsNullMIPSInstruction[] THEN { RETURN [relocated]; }; IF from.IsNullMIPSAddress[] THEN { ERROR MIPSArchitecture.NullMIPSAddress; }; IF to.IsNullMIPSAddress[] THEN { ERROR MIPSArchitecture.NullMIPSAddress; }; SELECT instruction.GetOp[] FROM special => SELECT instruction.GetOpSpecial[] FROM sll, srl, sra, sllv, srlv, srav => NULL; -- Shift jr => NULL; -- Jump Register jalr => NULL; -- Jump And Link Register syscall => NULL; -- System call exception break => NULL; -- Breakpoint trap sync => NULL; -- Synchronize mfhi, mthi, mflo, mtlo => NULL; -- Manipulate HI, LO registers mult, multu, div, divu => NULL; -- Arithmatic (use HI, LO registers) add, addu, sub, subu, and, or, xor, nor => NULL; -- Arithmatic slt, sltu => NULL; -- Set On Less Than tge, tgeu, tlt, tltu, teq, tne => NULL; -- Trap ENDCASE => ERROR; regimm => SELECT instruction.GetOpRegImm[] FROM bltz => relocated _ RelocateBranch[instruction, from, to]; bgez => relocated _ RelocateBranch[instruction, from, to]; bltzl => relocated _ RelocateBranch[instruction, from, to]; bgezl => relocated _ RelocateBranch[instruction, from, to]; tgei, tgeiu, tlti, tltiu, teqi, tnei => NULL; -- Trap bltzal => relocated _ RelocateBranch[instruction, from, to]; bgezal => relocated _ RelocateBranch[instruction, from, to]; bltzall => relocated _ RelocateBranch[instruction, from, to]; bgezall => relocated _ RelocateBranch[instruction, from, to]; ENDCASE => ERROR; j => relocated _ RelocateFormatJ[instruction, from, to]; jal => relocated _ RelocateFormatJ[instruction, from, to]; beq => relocated _ RelocateBranch[instruction, from, to]; bne => relocated _ RelocateBranch[instruction, from, to]; blez => relocated _ RelocateBranch[instruction, from, to]; bgtz => relocated _ RelocateBranch[instruction, from, to]; addi => NULL; addiu => NULL; slti => NULL; sltiu => NULL; andi => NULL; ori => NULL; xori => NULL; lui => NULL; cop0 => NULL; cop1 => NULL; cop2 => NULL; cop3 => NULL; beql => relocated _ RelocateBranch[instruction, from, to]; bnel => relocated _ RelocateBranch[instruction, from, to]; blezl => relocated _ RelocateBranch[instruction, from, to]; bgtzl => relocated _ RelocateBranch[instruction, from, to]; lb => NULL; lh => NULL; lwl => NULL; lw => NULL; lbu => NULL; lhu => NULL; lwr => NULL; sb => NULL; sh => NULL; swl => NULL; sw => NULL; swr => NULL; cache => NULL; ll => NULL; lwc1 => NULL; lwc2 => NULL; lwc3 => NULL; ldc1 => NULL; ldc2 => NULL; ldc3 => NULL; sc => NULL; swc1 => NULL; swc2 => NULL; swc3 => NULL; sdc1 => NULL; sdc2 => NULL; sdc3 => NULL; ENDCASE => ERROR; RETURN [relocated]; }; IsDelayedControlTransfer: PUBLIC PROCEDURE [ instruction: MIPSArchitecture.MIPSInstruction] RETURNS [BOOLEAN] ~ { hasDelayInstruction: BOOLEAN _ FALSE; IF instruction.IsNullMIPSInstruction[] THEN { RETURN [hasDelayInstruction]; }; SELECT instruction.GetOp[] FROM special => SELECT instruction.GetOpSpecial[] FROM sll, srl, sra, sllv, srlv, srav => NULL; -- Shift jr => NULL; -- Jump Register jalr => NULL; -- Jump And Link Register syscall => NULL; -- System call exception break => NULL; -- Breakpoint trap sync => NULL; -- Synchronize mfhi, mthi, mflo, mtlo => NULL; -- Manipulate HI, LO registers mult, multu, div, divu => NULL; -- Arithmatic (use HI, LO registers) add, addu, sub, subu, and, or, xor, nor => NULL; -- Arithmatic slt, sltu => NULL; -- Set On Less Than tge, tgeu, tlt, tltu, teq, tne => NULL; -- Trap ENDCASE => ERROR; regimm => SELECT instruction.GetOpRegImm[] FROM bltz => hasDelayInstruction _ TRUE; bgez => hasDelayInstruction _ TRUE; bltzl => hasDelayInstruction _ TRUE; bgezl => hasDelayInstruction _ TRUE; tgei, tgeiu, tlti, tltiu, teqi, tnei => NULL; -- Trap bltzal => hasDelayInstruction _ TRUE; bgezal => hasDelayInstruction _ TRUE; bltzall => hasDelayInstruction _ TRUE; bgezall => hasDelayInstruction _ TRUE; ENDCASE => ERROR; j => hasDelayInstruction _ TRUE; jal => hasDelayInstruction _ TRUE; beq => hasDelayInstruction _ TRUE; bne => hasDelayInstruction _ TRUE; blez => hasDelayInstruction _ TRUE; bgtz => hasDelayInstruction _ TRUE; addi => NULL; addiu => NULL; slti => NULL; sltiu => NULL; andi => NULL; ori => NULL; xori => NULL; lui => NULL; cop0 => NULL; cop1 => NULL; cop2 => NULL; cop3 => NULL; beql => hasDelayInstruction _ TRUE; bnel => hasDelayInstruction _ TRUE; blezl => hasDelayInstruction _ TRUE; bgtzl => hasDelayInstruction _ TRUE; lb => NULL; lh => NULL; lwl => NULL; lw => NULL; lbu => NULL; lhu => NULL; lwr => NULL; sb => NULL; sh => NULL; swl => NULL; sw => NULL; swr => NULL; cache => NULL; ll => NULL; lwc1 => NULL; lwc2 => NULL; lwc3 => NULL; ldc1 => NULL; ldc2 => NULL; ldc3 => NULL; sc => NULL; swc1 => NULL; swc2 => NULL; swc3 => NULL; sdc1 => NULL; sdc2 => NULL; sdc3 => NULL; ENDCASE => ERROR; RETURN [hasDelayInstruction]; }; noopInstruction: MIPSArchitecture.MIPSInstruction ~ MIPSArchitecture.Noop[]; IsNoopInstruction: PUBLIC PROCEDURE [instruction: MIPSArchitecture.MIPSInstruction] RETURNS [BOOLEAN] ~ { isNoopInstruction: BOOLEAN ~ instruction = noopInstruction; IF instruction.IsNullMIPSInstruction[] THEN { ERROR MIPSArchitecture.NullMIPSInstruction; }; RETURN [isNoopInstruction]; }; NeedsRelocation: PUBLIC PROCEDURE [instruction: MIPSArchitecture.MIPSInstruction] RETURNS [BOOLEAN] ~ { needsRelocation: BOOLEAN _ FALSE; IF instruction.IsNullMIPSInstruction[] THEN { ERROR MIPSArchitecture.NullMIPSInstruction; }; SELECT instruction.GetOp[] FROM special => SELECT instruction.GetOpSpecial[] FROM sll, srl, sra, sllv, srlv, srav => NULL; -- Shift jr => NULL; -- Jump Register jalr => NULL; -- Jump And Link Register syscall => NULL; -- System call exception break => NULL; -- Breakpoint trap sync => NULL; -- Synchronize mfhi, mthi, mflo, mtlo => NULL; -- Manipulate HI, LO registers mult, multu, div, divu => NULL; -- Arithmatic (use HI, LO registers) add, addu, sub, subu, and, or, xor, nor => NULL; -- Arithmatic slt, sltu => NULL; -- Set On Less Than tge, tgeu, tlt, tltu, teq, tne => NULL; -- Trap ENDCASE => ERROR; regimm => SELECT instruction.GetOpRegImm[] FROM bltz => needsRelocation _ TRUE; bgez => needsRelocation _ TRUE; bltzl => needsRelocation _ TRUE; bgezl => needsRelocation _ TRUE; tgei, tgeiu, tlti, tltiu, teqi, tnei => NULL; -- Trap bltzal => needsRelocation _ TRUE; bgezal => needsRelocation _ TRUE; bltzall => needsRelocation _ TRUE; bgezall => needsRelocation _ TRUE; ENDCASE => ERROR; j => needsRelocation _ TRUE; jal => needsRelocation _ TRUE; beq => needsRelocation _ TRUE; bne => needsRelocation _ TRUE; blez => needsRelocation _ TRUE; bgtz => needsRelocation _ TRUE; addi => NULL; addiu => NULL; slti => NULL; sltiu => NULL; andi => NULL; ori => NULL; xori => NULL; lui => NULL; cop0 => NULL; cop1 => NULL; cop2 => NULL; cop3 => NULL; beql => needsRelocation _ TRUE; bnel => needsRelocation _ TRUE; blezl => needsRelocation _ TRUE; bgtzl => needsRelocation _ TRUE; lb => NULL; lh => NULL; lwl => NULL; lw => NULL; lbu => NULL; lhu => NULL; lwr => NULL; sb => NULL; sh => NULL; swl => NULL; sw => NULL; swr => NULL; cache => NULL; ll => NULL; lwc1 => NULL; lwc2 => NULL; lwc3 => NULL; ldc1 => NULL; ldc2 => NULL; ldc3 => NULL; sc => NULL; swc1 => NULL; swc2 => NULL; swc3 => NULL; sdc1 => NULL; sdc2 => NULL; sdc3 => NULL; ENDCASE => ERROR; RETURN [needsRelocation]; }; IsBranchInstruction: PUBLIC PROCEDURE [ instruction: MIPSArchitecture.MIPSInstruction] RETURNS [BOOLEAN] ~ { isBranchInstruction: BOOLEAN _ FALSE; IF instruction.IsNullMIPSInstruction[] THEN { ERROR MIPSArchitecture.NullMIPSInstruction; }; SELECT instruction.GetOp[] FROM special => SELECT instruction.GetOpSpecial[] FROM sll, srl, sra, sllv, srlv, srav => NULL; -- Shift jr => NULL; -- Jump Register jalr => NULL; -- Jump And Link Register syscall => NULL; -- System call exception break => NULL; -- Breakpoint trap sync => NULL; -- Synchronize mfhi, mthi, mflo, mtlo => NULL; -- Manipulate HI, LO registers mult, multu, div, divu => NULL; -- Arithmatic (use HI, LO registers) add, addu, sub, subu, and, or, xor, nor => NULL; -- Arithmatic slt, sltu => NULL; -- Set On Less Than tge, tgeu, tlt, tltu, teq, tne => NULL; -- Trap ENDCASE => ERROR; regimm => SELECT instruction.GetOpRegImm[] FROM bltz => isBranchInstruction _ TRUE; bgez => isBranchInstruction _ TRUE; bltzl => isBranchInstruction _ TRUE; bgezl => isBranchInstruction _ TRUE; tgei => NULL; tgeiu => NULL; tlti => NULL; tltiu => NULL; teqi => NULL; tnei => NULL; bltzal => isBranchInstruction _ TRUE; bgezal => isBranchInstruction _ TRUE; bltzall => isBranchInstruction _ TRUE; bgezall => isBranchInstruction _ TRUE; ENDCASE => ERROR; j => isBranchInstruction _ TRUE; jal => isBranchInstruction _ TRUE; beq => isBranchInstruction _ TRUE; bne => isBranchInstruction _ TRUE; blez => isBranchInstruction _ TRUE; bgtz => isBranchInstruction _ TRUE; addi => NULL; addiu => NULL; slti => NULL; sltiu => NULL; andi => NULL; ori => NULL; xori => NULL; lui => NULL; cop0 => NULL; cop1 => NULL; cop2 => NULL; cop3 => NULL; beql => isBranchInstruction _ TRUE; bnel => isBranchInstruction _ TRUE; blezl => isBranchInstruction _ TRUE; bgtzl => isBranchInstruction _ TRUE; lb => NULL; lh => NULL; lwl => NULL; lw => NULL; lbu => NULL; lhu => NULL; lwr => NULL; sb => NULL; sh => NULL; swl => NULL; sw => NULL; swr => NULL; cache => NULL; ll => NULL; lwc1 => NULL; lwc2 => NULL; lwc3 => NULL; ldc1 => NULL; ldc2 => NULL; ldc3 => NULL; sc => NULL; swc1 => NULL; swc2 => NULL; swc3 => NULL; sdc1 => NULL; sdc2 => NULL; sdc3 => NULL; ENDCASE; RETURN [isBranchInstruction]; }; IsCallInstruction: PUBLIC PROCEDURE [instruction: MIPSArchitecture.MIPSInstruction] RETURNS [BOOLEAN] ~ { isCallInstruction: BOOLEAN _ FALSE; IF instruction.IsNullMIPSInstruction[] THEN { ERROR MIPSArchitecture.NullMIPSInstruction; }; SELECT instruction.GetOp[] FROM special => SELECT instruction.GetOpSpecial[] FROM jalr => isCallInstruction _ TRUE; ENDCASE; jal => isCallInstruction _ TRUE; ENDCASE; RETURN [isCallInstruction]; }; IsJumpInstruction: PUBLIC PROCEDURE [instruction: MIPSArchitecture.MIPSInstruction] RETURNS [BOOLEAN] ~ { isJumpInstruction: BOOLEAN _ FALSE; IF instruction.IsNullMIPSInstruction[] THEN { ERROR MIPSArchitecture.NullMIPSInstruction; }; SELECT instruction.GetOp[] FROM special => SELECT instruction.GetOpSpecial[] FROM jr => isJumpInstruction _ TRUE; ENDCASE; j => isJumpInstruction _ TRUE; ENDCASE; RETURN [isJumpInstruction]; }; GetFormat: PUBLIC PROCEDURE [instruction: MIPSArchitecture.MIPSInstruction] RETURNS [MIPSArchitecture.Format] ~ { format: MIPSArchitecture.Format ~ SELECT instruction.GetOp[] FROM special => MIPSArchitecture.Format.formatR, regimm => MIPSArchitecture.Format.formatSIRegImm, j => MIPSArchitecture.Format.formatJ, jal => MIPSArchitecture.Format.formatJ, beq => MIPSArchitecture.Format.formatSI, bne => MIPSArchitecture.Format.formatSI, blez => MIPSArchitecture.Format.formatSI, bgtz => MIPSArchitecture.Format.formatSI, addi => MIPSArchitecture.Format.formatSI, addiu => MIPSArchitecture.Format.formatSI, slti => MIPSArchitecture.Format.formatSI, sltiu => MIPSArchitecture.Format.formatSI, andi => MIPSArchitecture.Format.formatI, ori => MIPSArchitecture.Format.formatI, xori => MIPSArchitecture.Format.formatI, lui => MIPSArchitecture.Format.formatI, cop0 => MIPSArchitecture.Format.formatR, cop1 => MIPSArchitecture.Format.formatR, cop2 => MIPSArchitecture.Format.formatR, cop3 => MIPSArchitecture.Format.formatR, beql => MIPSArchitecture.Format.formatSI, bnel => MIPSArchitecture.Format.formatSI, blezl => MIPSArchitecture.Format.formatSI, bgtzl => MIPSArchitecture.Format.formatSI, lb => MIPSArchitecture.Format.formatSI, lh => MIPSArchitecture.Format.formatSI, lwl => MIPSArchitecture.Format.formatSI, lw => MIPSArchitecture.Format.formatSI, lbu => MIPSArchitecture.Format.formatSI, lhu => MIPSArchitecture.Format.formatSI, lwr => MIPSArchitecture.Format.formatSI, sb => MIPSArchitecture.Format.formatSI, sh => MIPSArchitecture.Format.formatSI, swl => MIPSArchitecture.Format.formatSI, sw => MIPSArchitecture.Format.formatSI, swr => MIPSArchitecture.Format.formatSI, cache => MIPSArchitecture.Format.formatSI, ll => MIPSArchitecture.Format.formatSI, lwc1 => MIPSArchitecture.Format.formatSI, lwc2 => MIPSArchitecture.Format.formatSI, lwc3 => MIPSArchitecture.Format.formatSI, ldc1 => MIPSArchitecture.Format.formatSI, ldc2 => MIPSArchitecture.Format.formatSI, ldc3 => MIPSArchitecture.Format.formatSI, sc => MIPSArchitecture.Format.formatSI, swc1 => MIPSArchitecture.Format.formatSI, swc2 => MIPSArchitecture.Format.formatSI, swc3 => MIPSArchitecture.Format.formatSI, sdc1 => MIPSArchitecture.Format.formatSI, sdc2 => MIPSArchitecture.Format.formatSI, sdc3 => MIPSArchitecture.Format.formatSI, ENDCASE => ERROR; IF instruction.IsNullMIPSInstruction[] THEN { ERROR MIPSArchitecture.NullMIPSInstruction; }; RETURN [format]; }; GetOp: PUBLIC PROCEDURE [instruction: MIPSArchitecture.MIPSInstruction] RETURNS [MIPSArchitecture.Op] ~ { formatI: MIPSArchitecture.FormatI ~ LOOPHOLE[instruction]; op: MIPSArchitecture.Op ~ formatI.op; IF instruction.IsNullMIPSInstruction[] THEN { ERROR MIPSArchitecture.NullMIPSInstruction; }; RETURN [op]; }; GetOpSpecial: PUBLIC PROCEDURE [instruction: MIPSArchitecture.MIPSInstruction] RETURNS [MIPSArchitecture.OpSpecial] ~ { formatR: MIPSArchitecture.FormatR ~ LOOPHOLE[instruction]; opspecial: MIPSArchitecture.OpSpecial ~ formatR.opspecial; IF instruction.IsNullMIPSInstruction[] THEN { ERROR MIPSArchitecture.NullMIPSInstruction; }; RETURN [opspecial]; }; GetOpRegImm: PUBLIC PROCEDURE [instruction: MIPSArchitecture.MIPSInstruction] RETURNS [MIPSArchitecture.OpRegImm] ~ { formatIRegImm: MIPSArchitecture.FormatIRegImm ~ LOOPHOLE[instruction]; opRegImm: MIPSArchitecture.OpRegImm ~ formatIRegImm.opRegImm; IF instruction.IsNullMIPSInstruction[] THEN { ERROR MIPSArchitecture.NullMIPSInstruction; }; RETURN [opRegImm]; }; GetDisp26: PUBLIC PROCEDURE [instruction: MIPSArchitecture.MIPSInstruction] RETURNS [MIPSArchitecture.Disp26] ~ { formatJ: MIPSArchitecture.FormatJ ~ LOOPHOLE[instruction]; disp26: MIPSArchitecture.Disp26 ~ formatJ.disp26; IF instruction.IsNullMIPSInstruction[] THEN { ERROR MIPSArchitecture.NullMIPSInstruction; }; RETURN [disp26]; }; GetDisp16: PUBLIC PROCEDURE [instruction: MIPSArchitecture.MIPSInstruction] RETURNS [MIPSArchitecture.Disp16] ~ { formatSI: MIPSArchitecture.FormatSI ~ LOOPHOLE[instruction]; disp16: MIPSArchitecture.Disp16 ~ formatSI.simm16; IF instruction.IsNullMIPSInstruction[] THEN { ERROR MIPSArchitecture.NullMIPSInstruction; }; RETURN [disp16]; }; GetImm16: PUBLIC PROCEDURE [instruction: MIPSArchitecture.MIPSInstruction] RETURNS [MIPSArchitecture.Imm16] ~ { formatI: MIPSArchitecture.FormatI ~ LOOPHOLE[instruction]; imm16: MIPSArchitecture.Imm16 ~ formatI.imm16; IF instruction.IsNullMIPSInstruction[] THEN { ERROR MIPSArchitecture.NullMIPSInstruction; }; RETURN [imm16]; }; GetSimm16: PUBLIC PROCEDURE [instruction: MIPSArchitecture.MIPSInstruction] RETURNS [MIPSArchitecture.Simm16] ~ { formatSI: MIPSArchitecture.FormatSI ~ LOOPHOLE[instruction]; simm16: MIPSArchitecture.Simm16 ~ formatSI.simm16; IF instruction.IsNullMIPSInstruction[] THEN { ERROR MIPSArchitecture.NullMIPSInstruction; }; RETURN [simm16]; }; Hi: PUBLIC PROCEDURE [value: CARD32] RETURNS [MIPSArchitecture.Imm16] ~ { hi: MIPSArchitecture.Imm16 ~ value / (CARD32[MIPSArchitecture.lastImm16] + 1); RETURN [hi]; }; Lo: PUBLIC PROCEDURE [value: CARD32] RETURNS [MIPSArchitecture.Imm16] ~ { lo: MIPSArchitecture.Imm16 ~ value MOD (CARD32[MIPSArchitecture.lastImm16] + 1); RETURN [lo]; }; HiLo: PUBLIC PROCEDURE[hi: MIPSArchitecture.Imm16, lo: MIPSArchitecture.Imm16] RETURNS [CARD32] ~ { hiLo: CARD32 ~ (hi * (CARD32[MIPSArchitecture.lastImm16] + 1)) + lo; RETURN [hiLo]; }; GetHighOrderBits: PUBLIC PROCEDURE [ address: MIPSArchitecture.MIPSAddress] RETURNS [MIPSArchitecture.HighOrderBits] ~ { addressFormat: MIPSArchitecture.AddressFormat ~ LOOPHOLE[address]; RETURN [addressFormat.high]; }; GetTargetBits: PUBLIC PROCEDURE [ address: MIPSArchitecture.MIPSAddress] RETURNS [MIPSArchitecture.Disp26] ~ { addressFormat: MIPSArchitecture.AddressFormat ~ LOOPHOLE[address]; RETURN [addressFormat.target]; }; GetTagBits: PUBLIC PROCEDURE [ address: MIPSArchitecture.MIPSAddress] RETURNS [MIPSArchitecture.TagBits] ~ { addressFormat: MIPSArchitecture.AddressFormat ~ LOOPHOLE[address]; RETURN [addressFormat.tag]; }; SetDisp16: PUBLIC PROCEDURE [ instruction: MIPSArchitecture.MIPSInstruction, disp16: MIPSArchitecture.Disp16] RETURNS [MIPSArchitecture.MIPSInstruction] ~ { formatSI: MIPSArchitecture.FormatSI _ LOOPHOLE[instruction]; IF instruction.IsNullMIPSInstruction[] THEN { ERROR MIPSArchitecture.NullMIPSInstruction; }; formatSI.simm16 _ disp16; RETURN [LOOPHOLE[formatSI]]; }; SetImm16: PUBLIC PROCEDURE [ instruction: MIPSArchitecture.MIPSInstruction, imm16: MIPSArchitecture.Imm16] RETURNS [MIPSArchitecture.MIPSInstruction] ~ { formatI: MIPSArchitecture.FormatI _ LOOPHOLE[instruction]; IF instruction.IsNullMIPSInstruction[] THEN { ERROR MIPSArchitecture.NullMIPSInstruction; }; formatI.imm16 _ imm16; RETURN [LOOPHOLE[formatI]]; }; SetSimm16: PUBLIC PROCEDURE [ instruction: MIPSArchitecture.MIPSInstruction, simm16: MIPSArchitecture.Simm16] RETURNS [MIPSArchitecture.MIPSInstruction] ~ { formatSI: MIPSArchitecture.FormatSI _ LOOPHOLE[instruction]; IF instruction.IsNullMIPSInstruction[] THEN { ERROR MIPSArchitecture.NullMIPSInstruction; }; formatSI.simm16 _ simm16; RETURN [LOOPHOLE[formatSI]]; }; IsNullMIPSAddress: PUBLIC PROCEDURE [address: MIPSArchitecture.MIPSAddress] RETURNS [BOOLEAN] ~ { isNullMIPSAddress: BOOLEAN ~ address = MIPSArchitecture.nullMIPSAddress; RETURN [isNullMIPSAddress]; }; MIPSAddressFromDisplacement: PUBLIC PROCEDURE [ address: MIPSArchitecture.MIPSAddress, displacement: TargetArchitecture.Displacement] RETURNS [MIPSArchitecture.MIPSAddress] ~ { targetAddress: TargetArchitecture.Address ~ MIPSArchitecture.TargetAddressFromMIPSAddress[mipsAddress: address]; displaced: TargetArchitecture.Address ~ TargetArchitecture.AddressFromDisplacement[ address: targetAddress, displacement: displacement]; mipsDisplaced: MIPSArchitecture.MIPSAddress ~ MIPSArchitecture.MIPSAddressFromTargetAddress[address: displaced]; IF address.IsNullMIPSAddress[] THEN { ERROR MIPSArchitecture.NullMIPSAddress; }; RETURN [mipsDisplaced]; }; DisplacementFromMIPSAddresses: PUBLIC PROCEDURE [ here: MIPSArchitecture.MIPSAddress, there: MIPSArchitecture.MIPSAddress] RETURNS [TargetArchitecture.Displacement] ~ { hereTarget: TargetArchitecture.Address ~ MIPSArchitecture.TargetAddressFromMIPSAddress[mipsAddress: here]; thereTarget: TargetArchitecture.Address ~ MIPSArchitecture.TargetAddressFromMIPSAddress[mipsAddress: there]; displacement: TargetArchitecture.Displacement ~ TargetArchitecture.DisplacementFromAddresses[ here: hereTarget, there: thereTarget]; IF here.IsNullMIPSAddress[] THEN { ERROR MIPSArchitecture.NullMIPSAddress; }; IF there.IsNullMIPSAddress[] THEN { ERROR MIPSArchitecture.NullMIPSAddress; }; RETURN [displacement]; }; IsNullMIPSInstruction: PUBLIC PROCEDURE [ instruction: MIPSArchitecture.MIPSInstruction] RETURNS [BOOLEAN] ~ { isNullMIPSInstruction: BOOLEAN ~ instruction = MIPSArchitecture.nullMIPSInstruction; RETURN [isNullMIPSInstruction]; }; NextMIPSInstruction: PUBLIC PROCEDURE [pc: MIPSArchitecture.MIPSAddress] RETURNS [MIPSArchitecture.MIPSAddress] ~ TRUSTED { targetPC: TargetArchitecture.Address ~ MIPSArchitecture.TargetAddressFromMIPSAddress[mipsAddress: pc]; nextInstruction: TargetArchitecture.Address ~ TargetArchitecture.NextInstruction[pc: targetPC]; nextMIPSInstruction: MIPSArchitecture.MIPSAddress ~ MIPSArchitecture.MIPSAddressFromTargetAddress[address: nextInstruction]; IF pc.IsNullMIPSAddress[] THEN { ERROR MIPSArchitecture.NullMIPSAddress; }; RETURN [nextMIPSInstruction]; }; PrevMIPSInstruction: PUBLIC PROCEDURE [pc: MIPSArchitecture.MIPSAddress] RETURNS [MIPSArchitecture.MIPSAddress] ~ { targetPC: TargetArchitecture.Address ~ MIPSArchitecture.TargetAddressFromMIPSAddress[mipsAddress: pc]; prevInstruction: TargetArchitecture.Address ~ TargetArchitecture.PrevInstruction[pc: targetPC]; prevMIPSInstruction: MIPSArchitecture.MIPSAddress ~ MIPSArchitecture.MIPSAddressFromTargetAddress[address: prevInstruction]; IF pc.IsNullMIPSAddress[] THEN { ERROR MIPSArchitecture.NullMIPSAddress; }; RETURN [prevMIPSInstruction]; }; MIPSAddressFromTargetAddress: PUBLIC PROCEDURE [ address: TargetArchitecture.Address] RETURNS [MIPSArchitecture.MIPSAddress] ~ { mipsAddress: MIPSArchitecture.MIPSAddress ~ LOOPHOLE[address]; IF mipsAddress.IsNullMIPSAddress[] THEN { ERROR MIPSArchitecture.NullMIPSAddress; }; RETURN [mipsAddress]; }; TargetAddressFromMIPSAddress: PUBLIC PROCEDURE [ mipsAddress: MIPSArchitecture.MIPSAddress] RETURNS [TargetArchitecture.Address] ~ { address: TargetArchitecture.Address ~ LOOPHOLE[mipsAddress]; IF mipsAddress.IsNullMIPSAddress[] THEN { ERROR MIPSArchitecture.NullMIPSAddress; }; RETURN [address]; }; MIPSContentsFromTargetContents: PUBLIC PROCEDURE [ contents: TargetArchitecture.Contents] RETURNS [MIPSArchitecture.MIPSContents] ~ { mipsContents: MIPSArchitecture.MIPSContents ~ LOOPHOLE[contents]; RETURN [mipsContents]; }; TargetContentsFromMIPSContents: PUBLIC PROCEDURE [ contents: MIPSArchitecture.MIPSContents] RETURNS [TargetArchitecture.Contents] ~ { targetContents: TargetArchitecture.Contents ~ LOOPHOLE[contents]; RETURN [targetContents]; }; MIPSInstructionFromTargetInstruction: PUBLIC PROCEDURE [ instruction: TargetArchitecture.Instruction] RETURNS [MIPSArchitecture.MIPSInstruction] ~ { mipsInstruction: MIPSArchitecture.MIPSInstruction ~ LOOPHOLE[instruction]; RETURN [mipsInstruction]; }; TargetInstructionFromMIPSInstruction: PUBLIC PROCEDURE [ instruction: MIPSArchitecture.MIPSInstruction] RETURNS [TargetArchitecture.Instruction] ~ { targetInstruction: TargetArchitecture.Instruction ~ LOOPHOLE[instruction]; RETURN [targetInstruction]; }; MIPSRegisterClassFromTargetRegisterClass: PUBLIC PROCEDURE [ registerClass: TargetArchitecture.RegisterClass] RETURNS [MIPSArchitecture.RegisterClass] ~ { mipsRegisterClass: MIPSArchitecture.RegisterClass ~ LOOPHOLE[registerClass]; SELECT mipsRegisterClass FROM none, globals, globalsAndIns, globalsInsAndFloats, globalsInsFloatsOutsAndLocals, all => { NULL; }; ENDCASE => { ERROR RuntimeError.BoundsFault; }; RETURN [mipsRegisterClass]; }; TargetRegisterClassFromMIPSRegisterClass: PUBLIC PROCEDURE [ registerClass: MIPSArchitecture.RegisterClass] RETURNS [TargetArchitecture.RegisterClass] ~ { targetRegisterClass: TargetArchitecture.RegisterClass ~ LOOPHOLE[registerClass]; SELECT registerClass FROM none, globals, globalsAndIns, globalsInsAndFloats, globalsInsFloatsOutsAndLocals, all => { NULL; }; ENDCASE => { ERROR RuntimeError.BoundsFault; }; RETURN [targetRegisterClass]; }; CantRelocate: PUBLIC ERROR ~ CODE; CantReach: PUBLIC ERROR ~ CODE; NullMIPSAddress: PUBLIC ERROR ~ CODE; NullMIPSInstruction: PUBLIC ERROR ~ CODE; }. : MIPSArchitectureImpl.mesa Copyright Σ 1992 by Xerox Corporation. All rights reserved. Katsuyuki Komatsu August 7, 1992 5:11 pm PDT Jas, October 15, 1992 9:53 am PDT Code Assembly. This is a ``SLL $0, $0, 0'', the recommended noop. 0x00000000. Relocates an instruction from the given address to another address. Instruction Classification. Checks whether the instruction at the given pc has a delay slot. A sample noop instruction. Checks whether the instruction at the given pc is a noop. Checks whether the instruction at the given pc has pc-relative operands. Checks whether the instruction is a conditional branch instruction. Checks whether the instruction is a call instruction. Checks whether the instruction is a jump instruction. Field accessors for instructions. Field accessors for address. Field assigners for instructions. Miscellaneous. Tests if its argument is the null MIPSAddress. Tests if its argument is the null MIPSInstruction. Returns the instruction address after the given one. Returns a pointer to the previous instruction. Yeah for being able to back up in instruction streams, boo for needing to. IF mipsInstruction.IsNullMIPSInstruction[] THEN { ERROR MIPSArchitecture.NullMIPSInstruction; }; IF instruction.IsNullMIPSInstruction[] THEN { ERROR MIPSArchitecture.NullMIPSInstruction; }; Errors. Given for attempts to relocate an instruction too far, etc. Given for attempts to generate pc-relative instructions that don't reach. Given during code generation when null addresses are supplied. Given when supplied instruction is the null instruction. Κ#^•NewlineDelimiter – "cedar" style™code™K™Kšœœ‘$˜DKšœ+œ‘ ˜>Kšœ œ‘˜&Kšœ"œ‘˜/Kšœœ˜——šœ ˜ šœ˜%Kšœ:˜:Kšœ:˜:Kšœ;˜;Kšœ;˜;Kšœ(œ‘˜5Kšœ<˜Kšœœ‘$˜DKšœ+œ‘ ˜>Kšœ œ‘˜&Kšœ"œ‘˜/Kšœœ˜——šœ ˜ šœ˜%Kšœœ˜#Kšœœ˜#Kšœœ˜$Kšœœ˜$Kšœ(œ‘˜5Kšœ œ˜%Kšœ œ˜%Kšœ!œ˜&Kšœ!œ˜&Kšœœ˜——Kšœœ˜ Kšœœ˜"Kšœœ˜"Kšœœ˜"Kšœœ˜#Kšœœ˜#Kšœœ˜ Kšœ œ˜Kšœœ˜ Kšœ œ˜Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜#Kšœœ˜#Kšœœ˜$Kšœœ˜$Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœ œ˜Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜—Kšœ˜Kšœ˜K˜—šœL˜LK™K˜—š Ÿœœ œ2œœ˜jJ™9Jšœœ!˜;J˜šœ%œ˜-Kšœ&˜+K˜—Jšœ˜J˜J™—š Ÿœœ œ2œœ˜hK™HKšœœœ˜!K˜šœ%œ˜-Kšœ&˜+K˜—šœ˜šœ ˜ šœ˜&Kšœ#œ‘˜1Kšœœ‘˜Kšœœ‘˜'Kšœ œ‘˜)Kšœ œ‘˜!Kšœœ‘˜Kšœœ‘˜>Kšœœ‘$˜DKšœ+œ‘ ˜>Kšœ œ‘˜&Kšœ"œ‘˜/Kšœœ˜——šœ ˜ šœ˜%Kšœœ˜Kšœœ˜Kšœœ˜ Kšœœ˜ Kšœ(œ‘˜5Kšœœ˜!Kšœœ˜!Kšœœ˜"Kšœœ˜"Kšœœ˜——Kšœœ˜Kšœœ˜Kšœœ˜Kšœœ˜Kšœœ˜Kšœœ˜Kšœœ˜ Kšœ œ˜Kšœœ˜ Kšœ œ˜Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜Kšœœ˜Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœ œ˜Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜—Jšœ˜K˜K˜—š Ÿœœ œ3œœ˜mK™CKšœœœ˜%K˜šœ%œ˜-Kšœ&˜+K˜—šœ˜šœ ˜ šœ˜&Kšœ#œ‘˜1Kšœœ‘˜Kšœœ‘˜'Kšœ œ‘˜)Kšœ œ‘˜!Kšœœ‘˜Kšœœ‘˜>Kšœœ‘$˜DKšœ+œ‘ ˜>Kšœ œ‘˜&Kšœ"œ‘˜/Kšœœ˜——šœ ˜ šœ˜%Kšœœ˜#Kšœœ˜#Kšœœ˜$Kšœœ˜$Kšœœ˜ Kšœ œ˜Kšœœ˜ Kšœ œ˜Kšœœ˜ Kšœœ˜ Kšœ œ˜%Kšœ œ˜%Kšœ!œ˜&Kšœ!œ˜&Kšœœ˜——Kšœœ˜ Kšœœ˜"Kšœœ˜"Kšœœ˜"Kšœœ˜#Kšœœ˜#Kšœœ˜ Kšœ œ˜Kšœœ˜ Kšœ œ˜Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜#Kšœœ˜#Kšœœ˜$Kšœœ˜$Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœ œ˜Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœœ˜ Kšœ˜—Jšœ˜K˜K˜—š Ÿœœ œ2œœ˜jK™5Kšœœœ˜#K˜šœ%œ˜-Kšœ&˜+K˜—šœ˜šœ ˜ šœ˜&Kšœœ˜!Kšœ˜——Kšœœ˜ Kšœ˜—Jšœ˜K˜K˜—š Ÿœœ œ2œœ˜jK™5Kšœœœ˜#K˜šœ%œ˜-Kšœ&˜+K˜—šœ˜šœ ˜ šœ˜&Kšœœ˜Kšœ˜——Kšœœ˜Kšœ˜—Jšœ˜K˜K˜——™!šŸ œœ œ2œ˜ršœ"˜"šœ˜Kšœ+˜+Kšœ1˜1Kšœ%˜%Kšœ'˜'Kšœ(˜(Kšœ(˜(Kšœ)˜)Kšœ)˜)Kšœ)˜)Kšœ*˜*Kšœ)˜)Kšœ*˜*Kšœ(˜(Kšœ'˜'Kšœ(˜(Kšœ'˜'Kšœ(˜(Kšœ(˜(Kšœ(˜(Kšœ(˜(Kšœ)˜)Kšœ)˜)Kšœ*˜*Kšœ*˜*Kšœ'˜'Kšœ'˜'Kšœ(˜(Kšœ'˜'Kšœ(˜(Kšœ(˜(Kšœ(˜(Kšœ'˜'Kšœ'˜'Kšœ(˜(Kšœ'˜'Kšœ(˜(Kšœ*˜*Kšœ'˜'Kšœ)˜)Kšœ)˜)Kšœ)˜)Kšœ)˜)Kšœ)˜)Kšœ)˜)Kšœ'˜'Kšœ)˜)Kšœ)˜)Kšœ)˜)Kšœ)˜)Kšœ)˜)Kšœ)˜)Kšœœ˜——K˜šœ%œ˜-Kšœ&˜+K˜—Kšœ ˜Kšœ˜K˜—šŸœœ œ2œ˜jKšœ$œ˜:Kšœ%˜%K˜šœ%œ˜-Kšœ&˜+K˜—Kšœ˜ Kšœ˜K˜—šŸ œœ œ2œ!˜xKšœ$œ˜:Kšœ:˜:K˜šœ%œ˜-Kšœ&˜+K˜—Kšœ ˜Kšœ˜K˜—šŸ œœ œ2œ ˜vKšœ0œ˜FKšœ=˜=K˜šœ%œ˜-Kšœ&˜+K˜—Kšœ ˜Kšœ˜K˜—šŸ œœ œ2œ˜rKšœ$œ˜:Kšœ1˜1K˜šœ%œ˜-Kšœ&˜+K˜—Kšœ ˜Kšœ˜K˜—šŸ œœ œ2œ˜rKšœ&œ˜K˜šœ!œ˜)Kšœ"˜'K˜—Kšœ˜K˜K˜—šŸœœ œ/œ!˜…Kšœ&œ˜K™—šŸœœœœ˜)K™8K™——L˜K™——…—uΆŸN