OpenCores
URL https://opencores.org/ocsvn/forwardcom/forwardcom/trunk

Subversion Repositories forwardcom

[/] [forwardcom/] [testsuite/] [tests_branch.as] - Rev 164

Go to most recent revision | Compare with Previous | Blame | View Log

/**************************  tests_branch.as  *******************************
* Author:        Agner Fog
* date created:  2021-07-07
* last modified: 2021-07-20
* Version:       1.11
* Project:       ForwardCom Test suite, assembly code
* Description:   Test jump, call, and branch instructions with general 
*                purpose registers
*
* This test program will test jump, call, and branch instructions and 
* output a list of which instructions are working for int8, int16, int32, 
* and int64 operands.
*
* Copyright 2021 GNU General Public License v.3 http://www.gnu.org/licenses
******************************************************************************/

// Library functions in libc_light.li
extern _puts:     function reguse=3,0            // write string + linefeed to stdout
extern _printf:   function reguse=0xF,0          // write formatted string to stdout

const section read ip                            // read-only data section
// Text strings:

text1: int8 "\nForwardCom test suite\nTest jump, call, and branch instructions"  // intro text,
       int8 "\nPress Run to continue"
       int8 "\n                          int8   int16  int32  int64", 0          // and heading
newline: int8 "\n", 0                                                            // newline
press_run: int8 "\nPress Run to continue", 0

format1: int8 "\n%-26s%3c%7c%7c%7c", 0           // format string for printing results

// text strings for each instruction:
text_sub_jz:              int8 "sub/jump_zero", 0
text_sub_jneg:            int8 "sub/jump_neg", 0
text_sub_jpos:            int8 "sub/jump_pos", 0
text_sub_joverfl:         int8 "sub/jump_overfl", 0
text_sub_jborrow:         int8 "sub/jump_borrow", 0

text_add_jz:              int8 "add/jump_zero", 0
text_add_jneg:            int8 "add/jump_neg", 0
text_add_jpos:            int8 "add/jump_pos", 0
text_add_joverfl:         int8 "add/jump_overfl", 0
text_add_jcarry:          int8 "add/jump_carry", 0

text_and_jz:              int8 "and/jump_zero", 0
text_or_jz:               int8 "or /jump_zero", 0
text_xor_jz:              int8 "xor/jump_zero", 0

text_test_bit_jtrue:      int8 "test_bit/jump_true", 0
text_test_bits_and_jtrue: int8 "test_bits_and/jump_true", 0
text_test_bits_or_jtrue:  int8 "test_bits_or/jump_true", 0

text_compare_jequal:      int8 "compare/jump_equal", 0
text_compare_jsbelow:     int8 "compare/jump_sbelow", 0
text_compare_jsabove:     int8 "compare/jump_sabove", 0
text_compare_jubelow:     int8 "compare/jump_ubelow", 0
text_compare_juabove:     int8 "compare/jump_uabove", 0

text_inc_compare_jbelow:  int8 "increment_compare/j_below", 0
text_inc_compare_jabove:  int8 "increment_compare/j_above", 0
text_sub_maxlen_jpos:     int8 "sub_maxlen/jump_pos", 0

text_jump_relative:       int8 "jump_relative pointer", 0
text_call_relative:       int8 "call_relative pointer", 0
text_jump_relative_table: int8 "jump_relative table", 0
text_call_relative_table: int8 "call_relative table", 0

text_jump_absolute:       int8 "jump absolute pointer", 0
text_call_absolute:       int8 "call absolute pointer", 0
text_jump_register:       int8 "jump to register", 0
text_call_register:       int8 "call to register", 0
text_jump_32:             int8 "jump 32 bit offset", 0
text_call_32:             int8 "call 32 bit offset", 0

// not supported:
//text_jump_64:           int8 "jump 64 bit absolute", 0
//text_call_64:           int8 "call 64 bit absolute", 0

// relative jump tables
jumptab8:  int8  (TARGET1-TARGET3)/4, (TARGET2-TARGET3)/4, 0, (TARGET4-TARGET3)/4, (TARGET5-TARGET3)/4, 0
jumptab16: int16 (TARGET1-TARGET3)/4, (TARGET2-TARGET3)/4, 0, (TARGET4-TARGET3)/4, (TARGET5-TARGET3)/4, 0
jumptab32: int32 (TARGET1-TARGET3)/4, (TARGET2-TARGET3)/4, 0, (TARGET4-TARGET3)/4, (TARGET5-TARGET3)/4, 0
jumptab64: int64 (TARGET1-TARGET3)/4, (TARGET2-TARGET3)/4, 0, (TARGET4-TARGET3)/4, (TARGET5-TARGET3)/4, 0

const end


code1 section execute                            // code section

__entry_point function public                    // skip startup code
_main function public

/* register use:
r0:  bits indicating success for int8, int16, int32, int64
r1:  operand
r2:  operand
r3:  result
r4:  scratch
r6:  int64 supported
r20: return address when testing jump
*/

// print intro text and heading
int64  r0 = address [text1]                      // address of string
//call   _puts                                   // print string and linefeed
call   _printf                                   // print string without linefeed

breakpoint                                       // debug breakpoint

int    r1 = 1
int    capab2 = write_capabilities(r1, 0)        // disable error trap for unknown instructions

// Test of each instruction:

// Test sub/jump_zero
int    r1 = 1
int    r0 = 1
int8   r2 = sub(r1,1), jump_zero A1
int    r0 = 0
A1:
int16  r3 = sub(r2,1), jump_zero A2
int32  r4 = r3 == 0xFFFF
int    r0 |= 2, mask = r4
       jump   A3
A2:    int r0 = 0
A3: 
int32  r3 = sub(r3,0xFFFF), jump_zero A4
       jump  A5
A4:    int r0 |= 4
A5:
int64  r4 = sub(r0,7), jump_nzero A8
int64  r1 = r0 | 1 << 60
int64  r4 = sub(r1,7), jump_zero A8
int    r0 |= 8
A8:
int64  r1 = address [text_sub_jz]
call   print_result


// Test sub/jump_neg
int    r1 = 0x100
int8   r3 = sub(r1,1), jump_neg A10
int    r0 = 0
       jump A11
A10:   int r0 = 1
A11:
int16  r3 = sub(r3,r3), jump_neg A12
int    r0 |= 2
       jump A13
A12:   int r0 = 0
A13:
int32  r2 = -8      // sub(r3,-8) would be converted to add(r3,8)
int32  r3 = sub(r3, r2), jump_nneg A14
       jump A15
A14:   int r4 = r3 == 8
       int r0 |= 4, mask = r4
A15:
int64  r2 = 9
int64  r4 = sub(r3,r2), jump_nneg A16
int64  r5 = r4 == -1
int64  r3 |= 1 << 62
int64  r4 = sub(r3,r2), jump_neg A16
int    r0 |= 8, mask = r5
A16:
int64  r1 = address [text_sub_jneg]
call   print_result


// Test sub/jump_pos
int    r1 = 1
int    r2 = 0x100
int8   r3 = sub(r2,r1), jump_pos A30
int    r0 = r3 == 0xFF
       jump A31
A30:   int r0 = 0
A31:
int16  r3 = sub(r1,r3), jump_pos A32
int    r4 = r3 == 0xFF02
int    r0 |= 2, mask = r4
jump   A33
A32:   int r0 = 0
A33:
int32  r3 = sub(r2,r2), jump_npos A34
int    r0 = 0
jump   A35
A34:   int r4 = r3 == 0
       int r0 |= 4, mask = r4
A35:
int64  r1 |= 1 << 62
int64  r3 = sub(r1,r2), jump_npos A36
int    r0 |= 8
A36:
int64  r1 = address [text_sub_jpos]
call   print_result


// Test sub/jump_overflow
int    r1 = 0xA0
int    r2 = 0x21
int8   r3 = sub(r1,r2), jump_overfl A40
int    r0 = 0
jump   A41
A40:   int r0 = 1
A41:
int    r1 = 0xA000
int    r2 = 0x2000
int16  r3 = sub(r1,r2), jump_overfl A42
int    r0 |= 2
jump   A43
A42:   int r0 = 0
A43:
int32  r1 = 0x50000000
int32  r2 = 0xD0000000
int32  r3 = sub(r1,r2), jump_overfl A44
int    r0 = 0
jump   A45
A44:   int r0 |= 4
A45:
int64  r3 = sub(r1,r2), jump_noverfl A46
jump   A47
A46:   int64 r4 = r3 == 0xFFFFFFFF80000000
       int r0 |= 8, mask = r4
A47:
int64  r1 = address [text_sub_joverfl]
call   print_result


// Test sub/jump_borrow
int    r1 = 0x1280
int    r2 = 0x1281
int8   r3 = sub(r1,r2), jump_borrow A50
int    r0 = 0
jump   A51
A50:   int r0 = 1
A51:
int16  r3 = sub(r1,r2), jump_nborrow A52
int32  r4 = r3 == 0x0000FFFF
int    r0 |= 2, mask = r4
A52:
int32  r3 = sub(r1,r2), jump_nborrow A54
int64  r4 = r3 == 0x0000FFFFFFFF
int    r0 |= 4, mask = r4
A54:
int64  r1 |= 1 << 60
int64  r3 = sub(r2,r1), jump_nborrow A56
int    r0 |= 8
A56:
int64  r1 = address [text_sub_jborrow]
call   print_result


// Test add/jump_zero
int    r1 = 0x1271
int    r2 = 0x128F
int8   r3 = add(r1,r2), jump_zero B0
int    r0 = 0
jump   B1
B0:    int r0 = 1
B1:
int16  r3 = add(r1,r2), jump_zero B2
int    r0 |= 2
B2:
int32  r2 = -0x1271
int32  r3 = add(r1,r2), jump_nzero B4
int    r0 |= 4
B4:
int64  r3 = add(r1,r2), jump_zero B6
int    r0 |= 8
B6:
int64  r1 = address [text_add_jz]
call   print_result


// Test add/jump_neg
int    r1 = 0x1261
int    r2 = 0x1220
int8   r3 = add(r1,r2), jump_neg B10
int    r0 = 0
jump   B11
B10:   int r0 = 1
B11:
int16  r3 = add(r1,r2), jump_neg B12
int    r0 |= 2
B12:
int32  r2 = -0x1262
int32  r3 = add(r1,r2), jump_nneg B14
int    r0 |= 4
B14:
int64  r3 = add(r1,r2), jump_neg B16
int    r0 |= 8
B16:
int64  r1 = address [text_add_jneg]
call   print_result


// Test add/jump_pos
int    r1 = 0x1261
int    r2 = 0x1220
int8   r3 = add(r1,r2), jump_npos B20
int    r0 = 0
jump   B21
B20:   int r0 = r3 == 0x81
B21:
int32  r2 = -r1
int16  r3 = add(r1,r2), jump_pos B22
int32  r4 = r3 == 0
int    r0 |= 2, mask = r4
B22:
int32  r3 = add(r2,0), jump_pos B24
int    r0 |= 4
B24:
int64  r3 = add(r1,r2), jump_npos B26
int64  r4 = r3 == 1 << 32
int    r0 |= 8, mask = r4
B26:
int64  r1 = address [text_add_jpos]
call   print_result


// Test add/jump_overfl
int32  r1 = 0x1261
int32  r2 = 0x1220
int8   r3 = add(r1,r2), jump_overfl B30
int    r0 = 0
jump   B31
B30:   int r0 = 1
B31:
int16  r3 = add(r1,r2), jump_overfl B32
int    r0 |= 2
B32:
int32  r2 = 0x7FFFF000
int32  r3 = add(r1,r2), jump_noverfl B34
int    r0 |= 4
B34:
int64  r3 = add(r1,r2), jump_overfl B36
int    r0 |= 8
B36:
int64  r1 = address [text_add_joverfl]
call   print_result


// Test add/jump_carry
int32  r1 = 0x1261
int32  r2 = 0x1220
int8   r3 = add(r1,r2), jump_ncarry B40
int    r0 = 0
jump   B41
B40:   int r0 = 1
B41:
int16  r3 = add(r1,r2), jump_carry B42
int    r0 |= 2
B42:
int32  r2 = -r1
int32  r3 = add(r1,r2), jump_ncarry B44
int    r0 |= 4
B44:
int64  r2 <<= 32
int64  r3 = add(r2,r2), jump_ncarry B46
int    r0 |= 8
B46:
int64  r1 = address [text_add_jcarry]
call   print_result


// Test and/jump_zero
int32  r1 = 0x0100F055
int32  r2 = 0x10AA
int8   r3 = and(r1,r2), jump_zero C0
int    r0 = 0
jump   C1
C0:    int r0 = 1
C1:
int16  r3 = and(r1,r2), jump_zero C2
int    r4 = r3 == 0x1000
int    r0 |= 2, mask = r4
C2:
int32  r2 = 0x02220FAA
int32  r3 = and(r1,r2), jump_nzero C4
int    r0 |= 4
C4:
int64  r1 |= 1 << 60
int64  r2 |= 1 << 60
int64  r3 = and(r1,r2), jump_zero C6
int64  r4 = r3 == 1 << 60
int    r0 |= 8, mask = r4
C6:
int64  r1 = address [text_and_jz]
call   print_result


// Test or/jump_zero
int32  r1 = 0xF055
int32  r2 = 0x0FAA
int8   r3 = or(r1,r2), jump_zero C10
int    r0 = r3 == 0xFF
jump   C11
C10:   int r0 = 0
C11:
int    r1 = 0
int    r2 = 0
int16  r3 = or(r1,r2), jump_nzero C12
int    r0 |= 2
C12:
int32  r1 = 1 << 31
int32  r3 = or(r1,r2), jump_zero C14
int32  r4 = r3 == 1 << 31
int    r0 |= 4, mask = r4
C14:
int64  r1 = 1 << 32
int64  r3 = or(r1,r2), jump_zero C16
int64  r4 = r3 == 1 << 32
int    r0 |= 8, mask = r4
C16:
int64  r1 = address [text_or_jz]
call   print_result


// Test xor/jump_zero
int32  r1 = 0xF055
int32  r2 = r1
int8   r3 = xor(r1,r2), jump_zero C20
int    r0 = 0
jump   C21
C20:   int r0 = 1
C21:
int    r2 = 0
int16  r3 = xor(r1,r2), jump_zero C22
int32  r4 = r3 == r1
int    r0 |= 2, mask = r4
C22:
int32  r1 = -r1
int32  r2 = r1
int32  r3 = xor(r1,r2), jump_nzero C24
int    r0 |= 4
C24:
int64  r1 |= 1 << 63
int64  r3 = xor(r1,r2), jump_zero C26
int    r0 |= 8
C26:
int64  r1 = address [text_xor_jz]
call   print_result


// Test test_bit/jump_true
int32  r1 = 0x12345678
int8   test_bit(r1,4), jump_true E0
int    r0 = 0
jump   E1
E0:    int r0 = 1
E1:
int16  test_bit(r1,8), jump_true E2
int    r0 |= 2
E2:
int32  test_bit(r1,21), jump_false E4
int    r0 |= 4
E4:
int64  test_bit(r1,33), jump_true E6
int64  r1 |= 1 << 33
int64  test_bit(r1,33), jump_false E6
int    r0 |= 8
E6:
int64  r1 = address [text_test_bit_jtrue]
call   print_result


// Test test_bits_and/jump_true
int32  r1 = 0x12345678
int32  r2 = 0x2670
int8   test_bits_and(r1,r2), jump_true E10
int    r0 = 0
jump   E11
E10:   int r0 = 1
E11:
int16  test_bits_and(r1,r2), jump_true E12
int    r0 |= 2
E12:
int32  test_bits_and(r1,r1), jump_false E14
int    r0 |= 4
E14:
int64  r2 = r1 | 1 << 50
int64  test_bits_and(r1,r2), jump_true E16
int    r0 |= 8
E16:
int64  r1 = address [text_test_bits_and_jtrue]
call   print_result


// Test test_bits_or/jump_true
int32  r1 = 0x12345678
int32  r2 = 0xC0
int8   test_bits_or(r1,r2), jump_false E20
int    r0 = 1
jump   E21
E20:   int r0 = 0
E21:
int16  test_bits_or(r1,0x1001), jump_false E22
int    r0 |= 2
E22:
int32  test_bits_or(r2,0x1001), jump_true E24
int    r0 |= 4
E24:
int32  r2 = r1 ^ -1
int64  test_bits_or(r2,r1), jump_false E26
int    r0 &= ~ 4
E26:
int64  r1 |= 1 << 60
int64  r2 |= 1 << 60
int64  test_bits_or(r2,r1), jump_false E28
int    r0 |= 8
E28:
int64  r1 = address [text_test_bits_or_jtrue]
call   print_result


int64  r0 = address [press_run]                  // press run to continue
call   _printf                                   // print string

breakpoint


// Test compare/jump_equal
int32  r1 = 0x222212AB
int32  r2 = 0x222213AB
int8   compare(r1,r2), jump_equal F0
int    r0 = 0
jump   F1
F0:    int r0 = 1
F1:
int16  compare(r1,r2), jump_equal F2
int    r0 |= 2
F2:
int32  r2 &= ~0x100
int32  compare(r1,r2), jump_nequal F4
int    r0 |= 4
F4:
int64  r1 ^= 1 << 60
int64  compare(r1,r2), jump_equal F6
int    r0 |= 8
F6:
int64  r1 = address [text_compare_jequal]
call   print_result


// Test compare/jump_sbelow
int    r1 = 0x1111997F
int    r2 = 0x22228880
int8   compare(r1,r2), jump_sbelow F10
int    r0 = 1
jump   F11
F10:   int r0 = 0
F11:
int16  compare(r1,r2), jump_sbelow F12
int    r0 |= 2
F12:
int32  compare(r1,r2), jump_saboveeq F14
int    r0 |= 4
F14:
int64  r2 |= 1 << 63
int64  compare(r1,r2), jump_sbelow F16
int    r0 |= 8
F16:
int64  r1 = address [text_compare_jsbelow]
call   print_result


// Test compare/jump_sabove
int    r1 = 0x1111997F
int    r2 = 0x22228880
int8   compare(r1,r2), jump_sbeloweq F20
int    r0 = 1
jump   F21
F20:   int r0 = 0
F21:
int16  compare(r1,r2), jump_sbeloweq F22
int    r0 |= 2
F22:
int32  compare(r1,r2), jump_sabove F24
int    r0 |= 4
F24:
int32  compare(r1,r1), jump_sbeloweq F25
int    r0 &= ~ 4
F25:
int64  r2 |= 1 << 63
int64  compare(r1,r2), jump_sbeloweq F26
int    r0 |= 8
F26:
int64  r1 = address [text_compare_jsabove]
call   print_result


// Test compare/jump_ubelow
int    r1 = 0x1111997F
int    r2 = 0x22228880
int8   compare(r1,r2), jump_ubelow F30
int    r0 = 0
jump   F31
F30:   int r0 = 1
F31:
int16  compare(r1,r2), jump_ubelow F32
int    r0 |= 2
F32:
int32  compare(r1,r2), jump_uaboveeq F34
int    r0 |= 4
F34:
int32  compare(r1,r1), jump_uaboveeq F35
int    r0 &= ~ 4
F35:
int64  compare(r1,r2), jump_uaboveeq F36
int64  r1 |= 1 << 63
int64  compare(r1,r2), jump_ubelow F36
int    r0 |= 8
F36:
int64  r1 = address [text_compare_jubelow]
call   print_result


// Test compare/jump_uabove
int    r1 = 0x1111997F
int    r2 = 0x22228880
int8   compare(r1,r2), jump_ubeloweq F40
int    r0 = 0
jump   F41
F40:   int r0 = 1
F41:
int16  compare(r1,r2), jump_ubeloweq F42
int    r0 |= 2
F42:
int32  compare(r1,r2), jump_uabove F44
int    r0 |= 4
F44:
int32  compare(r1,r1), jump_ubeloweq F45
int    r0 &= ~ 4
F45:
int64  compare(r1,r2), jump_uabove F46
int64  r1 |= 1 << 63
int64  compare(r1,r2), jump_ubeloweq F46
int    r0 |= 8
F46:
int64  r1 = address [text_compare_juabove]
call   print_result


// Test inc_compare/jump_below
int    r2 = 0
for (int8 r1 = 0; r1 < 5; r1++) {
    int r2++
}
int    r0 = r2 == 5
for (int16 r1 = 0x7000; r1 < 0x7005; r1++) {
    int r2++
}
int    r4 = r2 == 10
int    r0 |= 2, mask = r4

for (int32 r1 = -2; r1 < 3; r1++) {
    int r2++
}
int32  r4 = r2 == 15
int    r0 |= 4, mask = r4
int32  r1 = 0x7FFFFFFE
int64  r3 = r1 + 5
for (int64 ; r1 < r3; r1++) {
    int r2++
}
int32  r4 = r2 == 20
int    r0 |= 8, mask = r4
int64  r1 = address [text_inc_compare_jbelow]
call   print_result


// Test inc_compare/jump_above
int    r2 = 0
for (int8 r1 = 0; r1 <= 5; r1++) {
    int r2++
}
int    r0 = r2 == 6
int    r3 = 0x7005
for (int16 r1 = 0x7000; r1 <= r3; r1++) {
    int r2++
}
int    r4 = r2 == 12
int    r0 |= 2, mask = r4

for (int32 r1 = -2; r1 <= 3; r1++) {
    int r2++
}
int32  r4 = r2 == 18
int    r0 |= 4, mask = r4
int32  r1 = 0x7FFFFFFE
int64  r3 = r1 + 5
for (int64 ; r1 <= r3; r1++) {
    int r2++
}
int32  r4 = r2 == 24
int    r0 |= 8, mask = r4
int64  r1 = address [text_inc_compare_jabove]
call   print_result


// Test sub_maxlen/jump_pos
// get max vector length without using vectors:
int    r6 = 0
int64  r6 = sub_maxlen(r6, 3), jump_pos H1
int    r6 = - r6                                 // max vector length
int    r2 = 0
H1:    int r0 = 0
if (int r6 > 0) {                                // avoid infinite loops if maxlen = 0
  // test all operand sizes for completeness, even though only int64 is used. int8 is likely to overflow
  int   r1 = 4 
  H10:  int r2++
  int8  r1 = sub_maxlen(r1, 3), jump_pos H10
  int   r0 = r2 == 1

  int   r1 = r6 << 2
  int   r2 = 0
  H20:  int r2++
  int16 r1 = sub_maxlen(r1, 3), jump_pos H20
  int   r4 = r2 == 4
  int   r0 |= 2, mask = r4

  int   r1 = r6 << 2
  int   r1 += 4
  int   r2 = 0
  H30:  int r2++
  int32 r1 = sub_maxlen(r1, 3), jump_pos H30
  int   r4 = r2 == 5
  int   r0 |= 4, mask = r4

  int64 r3 = 1 << 60
  int64 r1 = sub_maxlen(r1, 3), jump_npos H42  
  int   r1 = r6 << 2
  int   r1 += 4
  int   r2 = 0
  H40:  int r2++
  int64 r1 = sub_maxlen(r1, 3), jump_pos H40
  int   r4 = r2 == 5
  int   r0 |= 8, mask = r4
  H42:
}
int64  r1 = address [text_sub_maxlen_jpos]
call   print_result


// Test jump to relative pointer in memory
int    r1 = 0
int64  r10 = address [TARGET3]
int64  r11 = address [jumptab8]
int64  r20 = address [K00]
int8   jump_relative(r10,[r11])
K00:   int r0 = r3 == 1

int64  r20 = address [K10]
int16  jump_relative(r10,[jumptab16+4])
K10:   int r4 = r3 == 3
int    r0 |= 2, mask = r4

int64  r20 = address [K20]
int32  jump_relative(r10,[jumptab32+4])
K20:   int r4 = r3 == 2
int    r0 |= 4, mask = r4

int64  r20 = address [K30]
int64  r11 = address [jumptab64]
int64  jump_relative(r10,[r11+24])
K30:   int r4 = r3 == 4
int    r0 |= 8, mask = r4

int64  r1 = address [text_jump_relative]
call   print_result


// Test call to relative pointer in memory
int    r1 = 0
int64  r20 = address [TARGETRETURN]
int64  r11 = address [jumptab8]
int8   call_relative(r10,[r11])
int r0 = r3 == 1

int16  call_relative(r10,[jumptab16+4])
int    r4 = r3 == 3
int    r0 |= 2, mask = r4

int32  call_relative(r10,[jumptab32+4])
int    r4 = r3 == 2
int    r0 |= 4, mask = r4

int64  r11 = address [jumptab64]
int64  call_relative(r10,[r11+24])
int r4 = r3 == 4
int    r0 |= 8, mask = r4

int64  r1 = address [text_call_relative]
call   print_result


// Test jump to relative table in memory
int    r1 = 0
int64  r10 = address [TARGET3]
int64  r11 = address [jumptab8]
int64  r20 = address [L00]
int8   jump_relative(r10,[r11+r1])
L00:   int r4 = r3
int    r1 = 1
int64  r20 = address [L01]
int8   jump_relative(r10,[r11+r1])
L01:   int r4 <<= 4
       int r4 |= r3
int    r1 = 4
int64  r20 = address [L02]
int8   jump_relative(r10,[r11+r1])
L02:   int r4 <<= 4
int    r4 |= r3
int    r0 = r4 == 0x125

int    r1 = 2
int64  r11 = address [jumptab16]
int64  r20 = address [L10]
int16  jump_relative(r10,[r11+r1*2])
L10:   int r4 = r3
int    r1 = 1
int64  r20 = address [L11]
int16  jump_relative(r10,[r11+r1*2])
L11:   int r4 <<= 4
       int r4 |= r3
int    r1 = 3
int64  r20 = address [L12]
int16  jump_relative(r10,[r11+r1*2])
L12:   int r4 <<= 4
int    r4 |= r3
int    r4 = r4 == 0x324
int    r0 |= 2, mask = r4

int    r1 = 4
int64  r11 = address [jumptab32]
int64  r20 = address [L20]
int32  jump_relative(r10,[r11+r1*4])
L20:   int r4 = r3
int    r1 = 2
int64  r20 = address [L21]
int32  jump_relative(r10,[r11+r1*4])
L21:   int r4 <<= 4
       int r4 |= r3
int    r1 = 3
int64  r20 = address [L22]
int32  jump_relative(r10,[r11+r1*4])
L22:   int r4 <<= 4
int    r4 |= r3
int    r4 = r4 == 0x534
int    r0 |= 4, mask = r4

int    r1 = 0
int64  r11 = address [jumptab64]
int64  r20 = address [L30]
int64  jump_relative(r10,[r11+r1*8])
L30:   int r4 = r3
int    r1 = 4
int64  r20 = address [L31]
int64  jump_relative(r10,[r11+r1*8])
L31:   int r4 <<= 4
       int r4 |= r3
int    r1 = 2
int64  r20 = address [L32]
int64  jump_relative(r10,[r11+r1*8])
L32:   int r4 <<= 4
int    r4 |= r3
int    r4 = r4 == 0x153
int    r0 |= 8, mask = r4

int64  r1 = address [text_jump_relative_table]
call   print_result


// Test call to relative table in memory
int    r1 = 2
int64  r10 = address [TARGET3]
int64  r11 = address [jumptab8]
int64  r20 = address [TARGETRETURN]
int8   call_relative(r10,[r11+r1])
int    r4 = r3
int    r1 = 4
int8   call_relative(r10,[r11+r1])
int    r4 <<= 4
int    r4 |= r3
int    r1 = 3
int8   call_relative(r10,[r11+r1])
int    r4 <<= 4
int    r4 |= r3
int    r0 = r4 == 0x354

int64  r11 = address [jumptab16]
int    r1 = 2
int16  call_relative(r10,[r11+r1*2])
int    r4 = r3
int    r1 = 0
int16  call_relative(r10,[r11+r1*2])
int    r4 <<= 4
int    r4 |= r3
int    r1 = 4
int16  call_relative(r10,[r11+r1*2])
int    r4 <<= 4
int    r4 |= r3
int    r4 = r4 == 0x315
int    r0 |= 2, mask = r4

int64  r11 = address [jumptab32]
int    r1 = 4
int32  call_relative(r10,[r11+r1*4])
int    r4 = r3
int    r1 = 1
int32  call_relative(r10,[r11+r1*4])
int    r4 <<= 4
int    r4 |= r3
int    r1 = 2
int32  call_relative(r10,[r11+r1*4])
int    r4 <<= 4
int    r4 |= r3
int    r4 = r4 == 0x523
int    r0 |= 4, mask = r4

int64  r11 = address [jumptab64]
int    r1 = 3
int64  call_relative(r10,[r11+r1*8])
int    r4 = r3
int    r1 = 4
int64  call_relative(r10,[r11+r1*8])
int    r4 <<= 4
int    r4 |= r3
int    r1 = 0
int64  call_relative(r10,[r11+r1*8])
int    r4 <<= 4
int    r4 |= r3
int    r4 = r4 == 0x451
int    r0 |= 8, mask = r4

int64  r1 = address [text_call_relative_table]
call   print_result


// jump/call 24 bit relative need not be tested because we would not have got here if they didn't work
// jump/call to register value need not be tested because we would not have got here if they didn't work
int    r0 = 0x78
int64  r1 = address [text_jump_register]
call   print_result
int    r0 = 0x78
int64  r1 = address [text_call_register]
call   print_result


int64  sp -= 32                                  // allocate space on stack

// test jump absolute address in memory
int64  r2 = address [TARGET2]
int64  r3 = address [TARGET3]
int64  [sp] = r2                                 // put jump target address on stack
int64  [sp+8] = r3                               // put jump target address on stack
int64  r20 = address [M10]                       // destination for jump back
int64  jump ([sp+8])                             // 8 bit offset, format 1.6.1B
nop
M10:   int r4 = r3 == 3
int64  r1 = sp + 0x1000
int64  r20 = address [M11]                       // destination for jump back
int64  jump ([r1-0x1000])                        // 32 bit offset, format 2.5.2B
nop
M11:   int r4 = r3 == 2 && r4
int    r0 = r4 ? 0x78 : 0

int64  r1 = address [text_jump_absolute]
call   print_result


// test call absolute address in memory
int64  r20 = address [TARGETRETURN]
int    r3 = 0
int64  call ([sp])                               // 8 bit offset, format 1.6.1B
int    r4 = r3 == 2
int    r0 = r4 ? 0x78 : 0
int64  r1 = address [text_call_absolute]
call   print_result


// test jump 32 bit relative
options codesize = 1 << 30                       // make sure to use 32-bit jump address
int64  r20 = address [M20]
int    r3 = 0
jump   TARGET4
nop
M20:
int    r4 = r3 == 4
int    r0 = r4 ? 0x78 : 0
int64  r1 = address [text_jump_32]
call   print_result


// test call 32 bit relative
int64  r20 = address [TARGETRETURN]
int    r3 = 0
call   TARGET3
nop
int    r4 = r3 == 3
int    r0 = r4 ? 0x78 : 0
int64  r1 = address [text_call_32]
call   print_result
options codesize = 0                             // return to default codesize

int64  sp += 32                                  // free allocated space on stack


int64 r0 = address [newline]
call   _printf                                   // print string


breakpoint

int r0 = 0                                       // program return value
return                                           // return from main

_main end


print_result function
// Print the result of a single test. Parameters:
// r0:  4 bits indicating success for for int8, int16, int32, int64. 4 additional bits for printing space (instruction not supported)
// r1:  pointer to text string 

// set up parameter list for printf
int64 sp -= 5*8              // allocate space on stack
int64 [sp] = r1              // text
int r4 = 'N'
int r2 = r0 ? 'Y' : r4       // Y or N
int r5 = test_bit(r0, 4)
int r2 = r5 ? ' ' : r2       // Y/N or space
int64 [sp+0x08] = r2         // result for int8
int r0 >>= 1
int r2 = r0 ? 'Y' : r4       // Y or N
int r5 = test_bit(r0, 4)
int r2 = r5 ? ' ' : r2       // Y/N or space
int64 [sp+0x10] = r2         // result for int16
int r0 >>= 1
int r2 = r0 ? 'Y' : r4       // Y or N
int r5 = test_bit(r0, 4)
int r2 = r5 ? ' ' : r2       // Y/N or space
int64 [sp+0x18] = r2         // result for int32
int r0 >>= 1
int r2 = r0 ? 'Y' : r4       // Y or N
int r5 = test_bit(r0, 4)
int r2 = r5 ? ' ' : r2       // Y/N or space
int64 [sp+0x20] = r2         // result for int64

int64 r0 = address [format1]
int64 r1 = sp
call _printf
int64 sp += 5*8              // release parameter list
return

print_result end

/*
(If you add more test outputs here, you need another breakpoint because 
 the output buffer is close to full and the screen on RealTerm will be 
 full as well.)
*/

code1 end


code2 section execute
// jump targets in a separate section for possible longer jump distance

TARGET1: int r3 = 1
jump  r20                    // jump back

TARGET2: int r3 = 2
jump  r20                    // jump back

TARGET3: int r3 = 3
jump  r20                    // jump back

TARGET4: int r3 = 4
jump  r20                    // jump back

TARGET5: int r3 = 5
jump  r20                    // jump back

TARGETRETURN: nop            // for call/return
return

code2 end

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.