URL
https://opencores.org/ocsvn/zipcpu/zipcpu/trunk
Subversion Repositories zipcpu
[/] [zipcpu/] [trunk/] [bench/] [asm/] [zipdhry.S] - Rev 53
Go to most recent revision | Compare with Previous | Blame | View Log
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Filename: zipdhry.S
;
; Project: Zip CPU -- a small, lightweight, RISC CPU soft core
;
; Purpose: Zip assembly file for running the Dhrystone benchmark in the
; Zip CPU.
;
; Creator: Dan Gisselquist, Ph.D.
; Gisselquist Tecnology, LLC
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Copyright (C) 2015, Gisselquist Technology, LLC
;
; This program is free software (firmware): you can redistribute it and/or
; modify it under the terms of the GNU General Public License as published
; by the Free Software Foundation, either version 3 of the License, or (at
; your option) any later version.
;
; This program is distributed in the hope that it will be useful, but WITHOUT
; ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
; for more details.
;
; License: GPL, v3, as defined and found on www.gnu.org,
; http://www.gnu.org/licenses/gpl.html
;
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
// Under Verilator:
// DMIPS: 25.57 100 MHz 0.26
// For comparison:
// uBlaze: 255 177 MHz 1.44
// LEON3 1.4
// NiOS II: 218 185 MHz 1.16
// OpenRisk 250 250 MHz 1.00
// LM32 1.14
// ZPU 2.6 50 MHz 0.05
//
// #define NO_LOOP_UNROLLING
#define SKIP_SHORT_CIRCUITS
sys.ctr.mtask equ 0xc0000008
// int main(int argc, char **argv) {
// dhrystone();
// }
entry:
MOV top_of_stack(PC),uSP
MOV entry(PC),uR12
; Store our tick counter in R1
LDI sys.ctr.mtask,R1
; And start with our counter cleared at zero
CLR R0
STO R0,(R1)
#ifdef SUPERVISOR_TASK
MOV __HERE__+3(PC),R0
STO R0,1(SP)
BRA dhrystone
#else
MOV dhrystone(PC),uPC
RTU
#endif
; Read the tick counter back out
LOD (R1),R0
HALT ; Stop the CPU--We're done!!!!!!!
// typedef enum { Ident_1, Ident_2, Ident_3, Ident_4, Ident_5 } test_enum;
// typedef enum { false, true } bool;
// typedef int Arr_1_Dim[50];
// typedef int Arr_2_Dim[50][50];
#define RECSIZE 35
#define NUMBER_OF_RUNS (512)
ptr_comp equ 0
discr equ 1
variant.var_1.enum_comp equ 2
variant.var_1.int_comp equ 3
variant.var_1.str_comp equ 4
gbl_arr_1:
fill 50,0
gbl_arr_2:
fill 2500,0
gbl_ch:
word 0
gbl_ch_2:
word 0
gbl_bool:
word 0
gbl_int:
word 0
gbl_ptr:
word 0
// Arr_1_Dim gbl_arr_1;
// Arr_2_Dim gbl_arr_2;
// char gbl_ch, gbl_ch_2;
// bool gbl_bool;
// int gbl_int;
// RECP gbl_ptr;
//char *lcl_strcpy(char *d, char *s) {
// char *cpd = d, ch;
//
// do{
// *cpd++ = ch = *s++;
// } while(ch);
//
//}
//
lcl_strcpy:
; R0 = d
; R1 = s
; R3 = ch
#ifdef NO_LOOP_UNROLLING
copy_next_char:
LOD (R1),R2
STO R2,(R0)
ADD 1,R0
ADD 1,R1
CMP 0,R2
BNZ copy_next_char
#else
copy_next_char:
LOD (R1),R2
CMP 0,R2
STO R2,(R0)
BZ lcl_strcpy_end_of_loop
LOD 1(R1),R2
CMP 0,R2
STO R2,1(R0)
BZ lcl_strcpy_end_of_loop
LOD 2(R1),R2
CMP 0,R2
STO R2,2(R0)
BZ lcl_strcpy_end_of_loop
LOD 3(R1),R2
CMP 0,R2
STO R2,3(R0)
BZ lcl_strcpy_end_of_loop
ADD 4,R0
ADD 4,R1
CMP 0,R2
BNZ copy_next_char
lcl_strcpy_end_of_loop:
#endif
RETN
//int lcl_strcmp(char *s1, char *s2) {
// char a, b;
// do {
// a = *s1++; b = *s2++;
// } while((a)&&(a==b));
//
// return a-b;
//}
lcl_strcmp:
SUB 1,SP
STO R3,1(SP)
strcmp_top_of_loop:
#ifdef NO_LOOP_UNROLLING
LOD (R0),R2
LOD (R1),R3 ; Alternate approach:
; CMP R2,R3 ; CMP 0,R2
; BNZ strcmp_end_loop ; BZ strcmp_end_loop
; CMP 0,R2 ; CMP R2,R3
; BZ strcmp_end_loop ; BZ strcmp_top_of_loop
; CMP 0,R3 ;
; BZ strcmp_end_loop ;
; ADD 1,R0
; ADD 1,R1
; BRA strcmp_top_of_loop
LOD (R0),R2
LOD (R1),R3
CMP 0,R2
BZ strcmp_end_loop
CMP R2,R3
BZ strcmp_top_of_loop
#else
LOD (R0),R2
LOD (R1),R3
CMP 0,R2
BZ strcmp_end_loop
CMP R2,R3
BNZ strcmp_end_loop
LOD 1(R0),R2
LOD 1(R1),R3
CMP 0,R2
BZ strcmp_end_loop
CMP R2,R3
BNZ strcmp_end_loop
LOD 2(R0),R2
LOD 2(R1),R3
CMP 0,R2
BZ strcmp_end_loop
CMP R2,R3
BNZ strcmp_end_loop
LOD 3(R0),R2
LOD 3(R1),R3
CMP 0,R2
BZ strcmp_end_loop
CMP R2,R3
BNZ strcmp_end_loop
ADD 4,R0
ADD 4,R1
BRA strcmp_top_of_loop
#endif
strcmp_end_loop:
SUB R3,R2
MOV R2,R0
LOD 1(SP),R3
ADD 1,SP
RETN
//test_enum func_1(char ch_1, char ch_2) {
// char lcl_ch_1, lcl_ch_2;
//
// lcl_ch_1 = ch_1;
// lcl_ch_2 = lcl_ch_1;
// if (lcl_ch_2 != ch_2)
// return 0;
// else {
// gbl_ch = lcl_ch_1;
// return 1;
// }
#ifdef NO_INLINE
func_1:
; On input,
; R0 = ch_1
; R1 = ch_2
; R2 = available
; On output, R0 is our return value
MOV R0,R2
CMP R2,R1
CLR.NZ R0
STO.Z R2,gbl_ch(R12)
LDILO.Z 1,R0
RETN
#endif
//bool func_2(char *str_1, char *str_2) {
// int lcl_int;
// char lcl_ch;
//
// lcl_int = 2;
// while(lcl_int <= 2) {
// if (func_1(str_1[lcl_int], str_2[lcl_int+1])==0) {
// lcl_ch = 'A';
// lcl_int ++;
// }
// }
//
// if ((lcl_ch >= 'W')&&(lcl_ch < 'Z'))
// lcl_int = 7;
// if (lcl_ch == 'R')
// return true;
// else {
// if (lcl_strcmp(str_1, str_2)>0) {
// lcl_int += 7;
// gbl_int = lcl_int;
// } else
// return false;
// }
//}
func_2:
;
SUB 6,SP
STO R3,2(SP)
STO R4,3(SP)
STO R5,4(SP)
STO R6,5(SP)
STO R7,6(SP)
MOV R0,R3 ; R3 = str_1
MOV R1,R4 ; R4 = str_2
LDI 2,R5 ; R5 = lcl_int
LDI 'A',R7 ; R7 = lcl_ch
func_2_while_loop:
CMP 2,R5
BGT func_2_end_while_loop
func_2_top_while_loop:
MOV R3,R6
ADD R5,R6
#ifdef NO_INLINE
LOD (R6),R0
MOV R4,R6
ADD R5,R6
LOD 1(R6),R1
MOV __HERE__+3(PC),R2
STO R2,1(SP)
BRA func_1
CMP 0,R0
ADD.Z 1,R5
#else
LOD (R6),R2
MOV R4,R6
ADD R5,R6
LOD 1(R6),R1
CMP R2,R1
STO.Z R2,gbl_ch(R12)
LDILO.Z 1,R0
ADD.NZ 1,R5
#endif
#ifndef SKIP_SHORT_CIRCUITS
BUSY.NZ
#endif
CMP 3,R5
#ifndef SKIP_SHORT_CIRCUITS
BUSY.LT
#endif
BLT func_2_top_while_loop
func_2_end_while_loop:
// CMP 'W',R7 // BUT! We know lcl_ch='A'
// BLT skip_if // So we can skip this
// CMP 'Z',R7 // entire section
// LDI.LT 7,R5
// CMP 'R',R7
// BNZ alt_if_case
// LLO.Z 1,R0
// BRA func_2_return_and_cleanup
//
MOV R3,R0
MOV R4,R1
MOV __HERE__+3(PC),R2
STO R2,1(SP)
BRA lcl_strcmp
CMP 0,R0
BGT func_2_final_then
#ifndef SKIP_SHORT_CIRCUITS
BUSY
#endif
CLR R0
BRA func_2_return_and_cleanup
func_2_final_then:
// ADD 7,R5 ; Never read, so useless code
LDI 1,R0
#ifndef SKIP_SHORT_CIRCUITS
BUSY
#endif
func_2_return_and_cleanup:
LOD 2(SP),R3
LOD 3(SP),R4
LOD 4(SP),R5
LOD 5(SP),R6
LOD 6(SP),R7
ADD 6,SP
RETN
//bool func_3(test_enum a) {
// test_enum lcl_enum;
//
// lcl_enum = a;
// if (lcl_enum == Ident_3)
// return true;
// else
// return false;
//}
#ifdef NO_INLINE
func_3:
; On entry,
; R0 = a
; R1 - available
CMP 2,R0
CLR R0 ; CLR Doesn't set flags
LDILO.Z 1,R0
RETN
#endif
// void proc_6(test_enum ev, test_enum *ep) {
// *ep = ev;
// if (!func_3(ev))
// *ep = 3;
// switch(ev) {
// case 0: *ep = 0; break;
// case 1:
// if (gbl_int > 100)
// *ep = 0;
// else
// *ep = 3;
// break;
// case 2:
// *ep = 1;
// break;
// case 3:
// break;
// case 4:
// *ep = 2;
// }
//}
proc_6:
; On entry:
; R0 = ev
; R1 = ep
; R2 - unassigned
; Since we call func_3, we have to reserve R0 and R1
; for other purposes. Thus
; R2 = ev
; R3 = ep
SUB 2,SP
STO R3,2(SP)
MOV R1,R3
MOV R0,R2
; *ep = ev
STO R0,(R1)
#ifndef SKIP_SHORT_CIRCUITS
CMP 2,R0
BUSY.NZ
#endif
#ifdef NO_INLINE
; !func_3(ev)
MOV __HERE__+3(PC),R1
STO R1,1(SP)
BRA func_3
TST -1,R0
LDI 3,R1
STO.Z R1,(R3)
#else
CMP 2,R0
LDI 3,R1
STO.Z R1,(R3)
#endif
TST -1,R0
LDI 3,R1
#ifndef SKIP_SHORT_CIRCUITS
BUSY.Z
#endif
STO.Z R1,(R3)
#ifndef SKIP_SHORT_CIRCUITS
CMP 2,R2
BUSY.NZ
#endif
CMP 0,R2
BNZ proc_6_case_not_zero
#ifndef SKIP_SHORT_CIRCUITS
BUSY
#endif
LDI 0,R1
STO R1,(R3)
BRA proc_6_end_of_case
proc_6_case_not_zero:
CMP 1,R2
BNZ proc_6_case_not_one
#ifndef SKIP_SHORT_CIRCUITS
BUSY
#endif
LDI 3,R0
LOD gbl_int(R12),R1
CMP 100,R1
CLR.GT R0
STO R0,(R3)
BRA proc_6_end_of_case
proc_6_case_not_one:
CMP 2,R2
BNZ proc_6_case_not_two
LDI 1,R1 // Executed, if done properly
STO R1,(R3)
BRA proc_6_end_of_case
proc_6_case_not_two:
#ifndef SKIP_SHORT_CIRCUITS
BUSY
#endif
CMP 4,R2
BNZ proc_6_case_not_four
LDI 2,R1
STO R1,(R3)
// BRA proc_6_end_of_case
proc_6_case_not_four:
proc_6_end_of_case:
LOD 2(SP),R3
ADD 2,SP
RETN
// void proc_7(int a, int b, int *c) {
// int lcl;
//
// lcl = a + 2;
// *c = b + a;
//}
#ifdef NO_INLINE
proc_7:
ADD 2+R0,R1
STO R1,(R2)
RETN
#endif
// int a[50];
// int b[50][50];
//
// void proc_8(Arr_1_Dim a, Arr_2_Dim b, int c, int d) {
// int idx, loc;
//
// loc = c+5;
// a[loc] = d;
// a[loc+1] = a[loc];
// a[loc+30] = loc;
// for(idx=loc; idx<= loc+1; idx++)
// b[loc][idx] = loc;
// b[loc][loc-1] += 1;
// b[loc+20][loc] = a[loc];
// gbl_int = 5;
//}
proc_8:
; R0 = a
; R1 = b
; R2 = c
; R3 = d
; R4 - unassigned
; Makes no function/procedure calls, so these can keep
; R2 = loc = c+5, replaces c
; R4 = idx
SUB 2,SP
STO R5,1(SP)
STO R6,2(SP)
ADD 5,R2 ; loc = c+5
MOV R0,R5
ADD R2,R5
STO R3,(R5)
STO R3,1(R5)
STO R2,30(R5)
MOV R2,R5
MPYU 50,R5 ; R5 = 50 * R2 = 50 * loc
ADD R1,R5 ; R5 = &b[loc][0]
MOV R5,R6 ; R6 = &b[loc][0]
ADD R2,R5 ; R5 = &b[loc][loc]
MOV R2,R4 ; R4 = loc = index
proc_8_top_of_loop:
CMP 1(R2),R4
BGT proc_8_end_of_loop
proc_8_loop_after_condition:
STO R2,(R5)
ADD 1,R5
ADD 1,R4
CMP 2(R2),R4
BLT proc_8_loop_after_condition
proc_8_end_of_loop:
; b[loc][loc-1] += 1
ADD R2,R6 ; R6 = &b[loc][loc]
LOD -1(R6),R5
ADD 1,R5
STO R5,-1(R6)
; b[loc+20][loc] = a[loc]
MOV R0,R4
ADD R2,R4
LOD (R4),R3
STO R3,20*50(R6)
LDI 5,R3
STO R3,gbl_int(R12)
LOD 1(SP),R5
LOD 2(SP),R6
ADD 2,SP
RETN
// void proc_5(void) {
// gbl_ch = 'A';
// gbl_bool = false;
//}
#ifdef NO_INLINE
proc_5:
LDI 'A',R0
STO R0,gbl_ch(R12)
CLR R0
STO R0,gbl_bool(R12)
;
RETN
#endif
// void proc_4(void) {
// bool lcl_bool;
// lcl_bool = (gbl_ch == 'A');
// gbl_ch_2 = 'B';
// }
#ifdef NO_INLINE
proc_4:
//
; LDI GBL,R12 // Already in R12
; Setting lcl_bool is irrelevant, so the optimizer should remove it.
; R0 doesn't need to be saved, since it's already trashed by the
; subroutine call.
;
; LOD gbl_ch(R12),R0
; CLR R1
; CMP 'A',R0
; ADD.Z 1,R1
;
LDI 'B',R0
STO R0,gbl_ch_2(R12)
;
RETN
#endif
// void proc_3(RECP *a) {
// if (gbl_ptr != NULL)
// *a = gbl_ptr->ptr_comp;
// proc_7(10,gbl_int, &gbl_ptr->variant.var_1.int_comp); // ??
//}
proc_3:
SUB 3,SP
STO R3,2(SP)
STO R2,3(SP)
; Save one for the return address from our JSR "instruction"
;
LOD gbl_ptr(R12),R2
TST -1,R2
#ifndef SKIP_SHORT_CIRCUITS
BUSY.Z
#endif
LOD.NZ ptr_comp(R2),R3
STO.NZ R3,(R0)
#ifdef NO_INLINE
LDI 10,R0
LOD gbl_int(R12),R1
MOV variant.var_1.int_comp(R2),R2
MOV __HERE__+3(PC),R3
STO R3,1(SP)
BRA proc_7
#else
LOD gbl_int(R12),R1
ADD 12,R1
STO R1,variant.var_1.int_comp(R2)
#endif
;
LOD 2(SP),R3
LOD 3(SP),R2
ADD 3,SP
RETN
// void proc_2(int *a) {
// int lcl_int;
// test_enum lcl_enum;
//
// lcl_int = *a + 10;
// do {
// if (gbl_ch == 'A') {
// lcl_int -= 1;
// *a = lcl_int - gbl_int;
// lcl_enum = Ident_1;
// }
// } while(lcl_enum != Ident_1);
//}
proc_2:
SUB 5,SP
STO R6,1(SP)
STO R5,2(SP)
STO R4,3(SP)
STO R3,4(SP)
STO R2,5(SP)
// R1 doesn't need to be stored, it was used in the subroutine
// call calculation
LOD (R0),R1
MOV 10(R1),R2 ; R2 = lcl_int
LOD gbl_ch(R12),R4 ; R4 = gbl_ch
#ifdef NO_CHEATING
proc_2_loop:
CMP 'A',R4
SUB.Z 1,R2
LOD.Z gbl_int(R12),R5 ; R5 = gbl_int
MOV.Z R2,R6 ; R6 = lcl_int
SUB.Z R5,R6 ; lcl_int - gbl_int
STO.Z R6,(R0) ; *a = R6
CLR.Z R3 ; lcl_enum = 0
// #ifndef SKIP_SHORT_CIRCUITS
// BUSY.NZ
// #endif
TST -1,R3
// #ifndef SKIP_SHORT_CIRCUITS
// BUSY.NZ
// #endif
BNZ proc_2_loop
#else
LOD gbl_int(R12),R5
SUB 1(R5),R2
STO R2,(R0)
#endif
;
LOD 1(SP),R6
LOD 2(SP),R5
LOD 3(SP),R4
LOD 4(SP),R3
LOD 5(SP),R2
ADD 5,SP
RETN
//void proc_1 (RECP a) {
// RECP nxt = a->ptr_comp;
//
// // structassign(a->ptr_comp, gbl_ptr);
// *(a->ptr_comp) = *(gbl_ptr);
//
// a->variant.var_1.int_comp = 5;
// nxt->variant.var_1.int_comp = a->variant.var_1.int_comp;
// proc_3(&nxt->ptr_comp);
//
// if (nxt->discr == 0) {
// nxt->variant.var_1.int_comp = 6;
// proc_6(a->variant.var_1.enum_comp, &nxt->variant.var_1.enum_comp);
// nxt->ptr_comp = gbl_ptr->ptr_comp;
// proc_7(nxt->variant.var_1.int_comp, 10, &nxt->variant.var_1.int_comp);
// } else
// // structassign(a, a->ptr_comp);
// *a = *(a->ptr_comp);
//}
proc_1:
SUB 9,SP
STO R2,2(SP)
STO R3,3(SP)
STO R4,4(SP)
STO R5,5(SP)
STO R6,6(SP)
STO R7,7(SP)
STO R8,8(SP)
STO R9,9(SP)
; R9 = a
; R4 = nxt
; R12 = GBL
; R13 = SP
MOV R0,R9
LOD ptr_comp(R9),R4
#ifndef SKIP_SHORT_CIRCUITS
TST -1,R4
BUSY.Z
#endif
LDI 35,R5
MOV R9,R6
LOD gbl_ptr(R12),R7
proc_1_assign_loop_1:
LOD (R6),R8
ADD 1,R6
STO R8,(R7)
ADD 1,R7
SUB 1,R5
BNZ proc_1_assign_loop_1;
#ifndef SKIP_SHORT_CIRCUITS
LOD gbl_ptr(R12),R2
TST -1,R2
BUSY.Z
#endif
LDI 5,R5
STO R5,variant.var_1.int_comp(R9)
STO R5,variant.var_1.int_comp(R4)
MOV ptr_comp(R4),R0
MOV __HERE__+3(PC),R1
STO R1,1(SP)
BRA proc_3 ; Uses R0 and R1
LOD discr(R4),R5
CMP 0,R5
BNZ proc_1_last_struct_assign
; This is the juncture that is "supposed" to be taken
LDI 6,R5
STO R5,variant.var_1.int_comp(R4)
LOD variant.var_1.enum_comp(R9), R0
#ifndef SKIP_SHORT_CIRCUITS
CMP 2,R0
BUSY.NZ
#endif
MOV variant.var_1.enum_comp+R4, R1
MOV __HERE__+3(PC),R2
STO R2,1(SP)
BRA proc_6
;
LOD gbl_ptr(R12),R5
LOD ptr_comp(R5),R5
STO R5,ptr_comp(R4)
;
#ifdef NO_INLINE
LOD variant.var_1.int_comp(R4),R0
LDI 10,R1
MOV variant.var_1.int_comp(R4),R2
MOV proc_1_return_closeout(PC),R3
STO R3,1(SP)
BRA proc_7
#else
LOD variant.var_1.int_comp(R4),R0
ADD 12,R0
STO R0,variant.var_1.int_comp(R4)
BRA proc_1_return_closeout
#endif
;
proc_1_last_struct_assign:
#ifndef SKIP_SHORT_CIRCUITS
BUSY
#endif
LDI 35,R4
MOV R2,R5
LOD gbl_ptr(R12),R6
proc_1_assign_loop_2:
LOD (R6),R8
STO R8,(R7)
ADD 1,R6
ADD 1,R7
SUB 1,R5
BNZ proc_1_assign_loop_2
//
proc_1_return_closeout:
//
LOD 2(SP),R2
LOD 3(SP),R3
LOD 4(SP),R4
LOD 5(SP),R5
LOD 6(SP),R6
LOD 7(SP),R7
LOD 8(SP),R8
LOD 9(SP),R9
ADD 9,SP
RETN
// void dhrystone(void) {
// int lcl_int_1, lcl_int_2, lcl_int_3, index, number_of_runs = 500;
// test_enum lcl_enum;
// char lcl_str_1[30], lcl_str_2[30], ch_index;
// REC_T a, b, *nxt = &a;
//
// gbl_ptr = &b;
// gbl_ptr->ptr_comp = nxt;
// gbl_ptr->variant.var_1.enum_comp = 2;
// gbl_ptr->variant.var_1.int_comp = 40;
// lcl_strcpy(gbl_ptr->variant.var_1.str_comp, "DHRYSTONE PROGRAM, SOME STRING");
// lcl_strcpy(lcl_str_1, "DHRYSTONE PROGRAM, 1\'ST STRING");
//
// gbl_arr_2[8][7] = 10;
//
// for(index=0; index < number_of_runs; index++) {
// proc_5();
// proc_4();
// lcl_int_1 = 2;
// lcl_int_2 = 3;
// lcl_strcpy(lcl_str_2, "DHRYSTONE PROGRAM, 2\'ND STRING");
// lcl_enum = Ident_2;
// gbl_bool = !func_2(lcl_str_1, lcl_str_2);
// while(lcl_int_1 < lcl_int_2) {
// lcl_int_3 = 5 * lcl_int_1 - lcl_int_2;
// proc_7(lcl_int_1, lcl_int_2, &lcl_int_3);
// lcl_int_1 += 1;
// }
//
// proc_8(gbl_arr_1, gbl_arr_2, lcl_int_1, lcl_int_3);
// proc_1(gbl_ptr);
//
// for(ch_index='A'; ch_index <= gbl_ch_2; ch_index++) {
// if (lcl_enum == func_1(ch_index, 'C')) {
// // Then not executed??
// proc_6(0, &lcl_enum);
// lcl_strcpy(lcl_str_2, "DHRYSTONE PROGRAM, 3\'RD STRING");
// lcl_int_2 = index;
// gbl_int = index;
// }
// }
//
// lcl_int_2 = lcl_int_2 * lcl_int_1;
// lcl_int_1 = lcl_int_2 / lcl_int_3;
// lcl_int_2 = 7 * ( lcl_int_2 - lcl_int_3) - lcl_int_1;
// proc_2(&lcl_int_1);
// }
//}
some_string:
word 'D','H','R','Y','S','T','O','N','E',' '
word 'P','R','O','G','R','A','M',',',' '
word 'S','O','M','E',' ','S','T','R','I','N','G'
word 0
first_string:
word 'D','H','R','Y','S','T','O','N','E',' '
word 'P','R','O','G','R','A','M',','
word ' ','1','\'','S','T'
word ' ','S','T','R','I','N','G'
word 0
second_string:
word 'D','H','R','Y','S','T','O','N','E',' '
word 'P','R','O','G','R','A','M',',',' '
word '2','\'','N','D',' ','S','T','R','I','N','G'
word 0
third_string:
word 'D','H','R','Y','S','T','O','N','E',' '
word 'P','R','O','G','R','A','M',',',' '
word '3','\'','R','D',' ','S','T','R','I','N','G'
word 0
dhrystone:
#ifdef SUPERVISOR_TASK
SUB 12+RECSIZE+RECSIZE+30+30+3,SP
; Leave a space on the top of the stack for calling
; subroutines.
STO R1,2(SP)
STO R2,3(SP)
STO R3,4(SP)
STO R4,5(SP)
STO R5,6(SP)
STO R6,7(SP)
STO R7,8(SP)
STO R8,9(SP)
STO R9,10(SP)
STO R10,11(SP)
STO R11,12(SP)
lcl_int_1 equ 12 ; plus SP
#else
lcl_int_1 equ 2 ; plus SP
SUB 2+RECSIZE+RECSIZE+30+30+3,SP
#endif
// 12 is the global variable pointer
// 13 is our stack
// 14 is our condition code register
// 15 is the program counter
;
lcl_int_3 equ lcl_int_1+1 ; plus SP
lcl_enum equ lcl_int_3+1 ; plus SP
lcl_str_1 equ lcl_enum+1 ; plus SP
lcl_str_2 equ lcl_str_1+30 ; plus SP
rec_a equ lcl_str_2+30 ; plus SP
rec_b equ rec_a+RECSIZE ; plus SP
// int lcl_int_1, lcl_int_2, lcl_int_3, index, number_of_runs = 500;
// test_enum lcl_enum;
// char lcl_str_1[30], lcl_str_2[30], ch_index;
// REC_T a, b, *nxt = &a;
//
// gbl_ptr = &b;
MOV rec_b(SP),R0 ; R0 = &b
STO R0,gbl_ptr(PC)
// gbl_ptr->ptr_comp = nxt;
MOV rec_a(SP),R1 ; R1 = &a = nxt
STO R1,ptr_comp(R0) ; gbp_ptr->ptr.comp=b->ptr.comp=R1=nxt
// gbl_ptr->variant.var_1.enum_comp = 2;
LDI 2,R2
STO R2,variant.var_1.enum_comp(R0)
// gbl_ptr->variant.var_1.int_comp = 40;
LDI 40,R2
STO R2,variant.var_1.int_comp(R0)
// lcl_strcpy(gbl_ptr->variant.var_1.str_comp, "DHRYSTONE PROGRAM, SOME STRING");
MOV variant.var_1.str_comp(R0),R0
MOV some_string(PC),R1
MOV __HERE__+3(PC),R2
STO R2,1(SP)
BRA lcl_strcpy
// lcl_strcpy(lcl_str_1, "DHRYSTONE PROGRAM, 1\'ST STRING");
MOV lcl_str_1(SP),R0
MOV first_string(PC),R1
MOV __HERE__+3(PC),R2
STO R2,1(SP)
BRA lcl_strcpy
// gbl_arr_2[8][7] = 10;
LDI 10,R0
STO R0,8*50+7+gbl_arr_2(R12)
//
// for(index=0; index < number_of_runs; index++) {
; Let R11 be our index
CLR R11
dhrystone_main_loop:
;; Start of Dhrystone main loop
; proc_5();
#ifdef NO_INLINE
MOV __HERE__+3(PC),R0
STO R0,1(SP)
BRA proc_5
#else
LDI 'A',R0
STO R0,gbl_ch(R12)
CLR R0
STO R0,gbl_bool(R12)
#endif
; proc_4();
#ifdef NO_INLINE
MOV __HERE__+3(PC),R0
STO R0,1(SP)
BRA proc_4
#else
LDI 'B',R0
STO R0,gbl_ch_2(R12)
#endif
// lcl_int_1 = 2;
LDI 2,R5
STO R5,lcl_int_1(SP)
// lcl_int_2 = 3;
LDI 3,R6
// lcl_strcpy(lcl_str_2, "DHRYSTONE PROGRAM, 2\'ND STRING");
MOV lcl_str_2(SP),R0
MOV second_string(PC),R1
MOV __HERE__+3(PC),R2
STO R2,1(SP)
BRA lcl_strcpy
// lcl_enum = Ident_2;
LDI 2,R0
STO R0,lcl_enum(SP)
// gbl_bool = !func_2(lcl_str_1, lcl_str_2);
MOV lcl_str_1(SP),R0
MOV lcl_str_2(SP),R1
MOV __HERE__+3(PC),R2
STO R2,1(SP)
BRA func_2
CLR R1
TST -1,R0
LDILO.Z 1,R1
STO R1,gbl_bool(PC)
// while(lcl_int_1 < lcl_int_2) {
; R5 = lcl_int_1 = 2 on entry
; R6 = lcl_int_2 = 3 on entry, so no entry test is required
LOD lcl_int_1(SP),R5
// The 'while' comparison
CMP R6,R5
BGE dhrystone_end_while_loop
dhrystone_while_loop:
// lcl_int_3 = 5 * lcl_int_1 - lcl_int_2;
MOV R5,R7
MPYS 5,R7
SUB R6,R7
STO R7,lcl_int_3(SP)
// proc_7(lcl_int_1, lcl_int_2, &lcl_int_3);
#ifdef NO_INLINE
MOV R5,R0
MOV R6,R1
MOV lcl_int_3(SP),R2
MOV __HERE__+3(PC),R3
STO R3,1(SP)
BRA proc_7
#else
MOV R6,R1
ADD 2+R5,R1
STO R1,lcl_int_3(SP)
#endif
// lcl_int_1 += 1;
LOD lcl_int_1(SP),R5
ADD 1,R5
STO R5,lcl_int_1(SP)
;
; BRA dhrystone_while_loop ; We'll unroll the loop, and put an
CMP R6,R5 ; additional comparison at the bottom
BLT dhrystone_while_loop
dhrystone_end_while_loop:
// }
//
// proc_8(gbl_arr_1, gbl_arr_2, lcl_int_1, lcl_int_3);
MOV gbl_arr_1(PC),R0
MOV gbl_arr_2(PC),R1
MOV R5,R2
MOV R6,R3
MOV __HERE__+3(PC),R4
STO R4,1(SP)
BRA proc_8
// proc_1(gbl_ptr);
LOD gbl_ptr(PC),R0
MOV __HERE__+3(PC),R2
STO R2,1(SP)
BRA proc_1
//
// for(ch_index='A'; ch_index <= gbl_ch_2; ch_index++) {
LDI 'A',R7
LOD gbl_ch_2(SP),R8
CMP R7,R8
BLT dhrystone_end_of_for_loop
dhrystone_top_of_for_loop:
// if (lcl_enum == func_1(ch_index, 'C')) {
#ifdef NO_INLINE
MOV R7,R0
LDI 'C',R1
MOV __HERE__+3(PC),R2
STO R2,1(SP)
BRA func_1
#else
CMP 'C',R7
CLR.NZ R0
STO.Z R7,gbl_ch(R12)
LDILO.Z 1,R0
#endif
; Result is now in R0
LOD lcl_enum(SP),R1
CMP R0,R1
BNZ dhrystone_skip_then_clause
// // Then not executed??
// proc_6(0, &lcl_enum);
#ifndef SKIP_SHORT_CIRCUITS
BUSY
#endif
CLR R0
MOV lcl_enum(SP),R1
MOV __HERE__+3(PC),R2
STO R2,1(SP)
BRA proc_6
// lcl_strcpy(lcl_str_2, "DHRYSTONE PROGRAM, 3\'RD STRING");
MOV lcl_str_2(SP),R0
MOV third_string(PC),R1
MOV __HERE__+3(PC),R2
STO R2,1(SP)
BRA lcl_strcpy
// lcl_int_2 = index;
MOV R11,R6
// gbl_int = index;
STO R11,gbl_int(PC)
// }
dhrystone_skip_then_clause:
ADD 1,R7
LOD gbl_ch_2(SP),R8
CMP R8,R7
BGE dhrystone_top_of_for_loop
dhrystone_end_of_for_loop:
// }
//
// lcl_int_2 = lcl_int_2 * lcl_int_1;
LOD lcl_int_1(SP),R5
MPYS R5,R6 ; lcl_int_2 =
// lcl_int_1 = lcl_int_2 / lcl_int_3;
#ifndef SKIP_DIVIDE
MOV R6,R0
LOD lcl_int_3(SP),R1
MOV __HERE__+3(PC),R2
STO R2,1(SP)
BRA divs
#else
LDI 9,R0
#endif
STO R0,lcl_int_1(SP)
// lcl_int_2 = 7 * ( lcl_int_2 - lcl_int_3) - lcl_int_1;
LOD lcl_int_3(SP),R2
SUB R2,R6
MPYS 7,R6
SUB R0,R6
// proc_2(&lcl_int_1);
MOV lcl_int_1(SP),R0
MOV __HERE__+3(PC),R1
STO R1,1(SP)
BRA proc_2
;; Bottom of (and return from) Dhrystone main loop
ADD 1,R11
CMP NUMBER_OF_RUNS,R11
BLT dhrystone_main_loop
// }
#ifdef SUPERVISOR_TASK
LOD 2(SP),R1
LOD 3(SP),R2
LOD 4(SP),R3
LOD 5(SP),R4
LOD 6(SP),R5
LOD 7(SP),R6
LOD 8(SP),R7
LOD 9(SP),R8
LOD 10(SP),R9
LOD 11(SP),R10
LOD 12(SP),R11
;
ADD 12+RECSIZE+RECSIZE+30+30+3,SP
; Return from subroutine
RETN
#else
LDI 0,CC
NOP
NOP
BUSY
#endif
Go to most recent revision | Compare with Previous | Blame | View Log