diff options
Diffstat (limited to 'mixlib')
| -rw-r--r-- | mixlib/mix_ins.c | 3 | ||||
| -rw-r--r-- | mixlib/mix_ins.h | 4 | ||||
| -rw-r--r-- | mixlib/mix_types.c | 34 | ||||
| -rw-r--r-- | mixlib/mix_types.h | 11 | ||||
| -rw-r--r-- | mixlib/testsuite/mix_vm_ins_t.c | 17 | ||||
| -rw-r--r-- | mixlib/xmix_vm.c | 14 | 
6 files changed, 80 insertions, 3 deletions
diff --git a/mixlib/mix_ins.c b/mixlib/mix_ins.c index 42cdafc..5838690 100644 --- a/mixlib/mix_ins.c +++ b/mixlib/mix_ins.c @@ -39,6 +39,7 @@ static const struct mix_ins_desc_ id_to_desc_[] =  {    IDESX_(5,0,NUM), IDESX_(5,1,CHAR), IDESX_(5,2,HLT),    IDESX_(6,0,SLA), IDESX_(6,1,SRA), IDESX_(6,2,SLAX), IDESX_(6,3,SRAX),    IDESX_(6,4,SLC), IDESX_(6,5,SRC), +  IDESX_(6,6,SLB), IDESX_(6,7,SRB),    IDES_(7,1,MOVE), IDES_(8,5,LDA), IDES_(9,5,LD1), IDES_(10,5,LD2),    IDES_(11,5,LD3), IDES_(12,5,LD4), IDES_(13,5,LD5),    IDES_(14,5,LD6), IDES_(15,5,LDX), IDES_(16,5,LDAN), IDES_(17,5,LD1N), @@ -53,6 +54,7 @@ static const struct mix_ins_desc_ id_to_desc_[] =  {    IDESX_(39,8,JNE), IDESX_(39,9,JLE),    IDESX_(40,0,JAN), IDESX_(40,1,JAZ), IDESX_(40,2,JAP), IDESX_(40,3,JANN),    IDESX_(40,4,JANZ), IDESX_(40,5,JANP), +  IDESX_(40,6,JAE), IDESX_(40,7,JAO),    IDESX_(41,0,J1N), IDESX_(41,1,J1Z), IDESX_(41,2,J1P), IDESX_(41,3,J1NN),    IDESX_(41,4,J1NZ), IDESX_(41,5,J1NP),    IDESX_(42,0,J2N), IDESX_(42,1,J2Z), IDESX_(42,2,J2P), IDESX_(42,3,J2NN), @@ -67,6 +69,7 @@ static const struct mix_ins_desc_ id_to_desc_[] =  {    IDESX_(46,4,J6NZ), IDESX_(46,5,J6NP),    IDESX_(47,0,JXN), IDESX_(47,1,JXZ), IDESX_(47,2,JXP), IDESX_(47,3,JXNN),    IDESX_(47,4,JXNZ), IDESX_(47,5,JXNP), +  IDESX_(47,6,JXE), IDESX_(47,7,JXO),    IDESX_(48,0,INCA), IDESX_(48,1,DECA), IDESX_(48,2,ENTA), IDESX_(48,3,ENNA),    IDESX_(49,0,INC1), IDESX_(49,1,DEC1), IDESX_(49,2,ENT1), IDESX_(49,3,ENN1),    IDESX_(50,0,INC2), IDESX_(50,1,DEC2), IDESX_(50,2,ENT2), IDESX_(50,3,ENN2), diff --git a/mixlib/mix_ins.h b/mixlib/mix_ins.h index 1ea3f81..a9267ad 100644 --- a/mixlib/mix_ins.h +++ b/mixlib/mix_ins.h @@ -47,7 +47,7 @@ typedef enum {  typedef enum {    mix_NOP,  mix_ADD, mix_SUB, mix_MUL, mix_DIV,    mix_NUM, mix_CHAR, mix_HLT, -  mix_SLA, mix_SRA, mix_SLAX, mix_SRAX, mix_SLC, mix_SRC, +  mix_SLA, mix_SRA, mix_SLAX, mix_SRAX, mix_SLC, mix_SRC, mix_SLB, mix_SRB,    mix_MOVE, mix_LDA, mix_LD1, mix_LD2, mix_LD3, mix_LD4, mix_LD5,    mix_LD6,  mix_LDX, mix_LDAN, mix_LD1N, mix_LD2N, mix_LD3N, mix_LD4N,    mix_LD5N, mix_LD6N, mix_LDXN, mix_STA, mix_ST1, mix_ST2, mix_ST3, mix_ST4, @@ -56,6 +56,7 @@ typedef enum {    mix_JMP, mix_JSJ, mix_JOV, mix_JNOV, mix_JL, mix_JE, mix_JG, mix_JGE,    mix_JNE, mix_JLE,    mix_JAN, mix_JAZ, mix_JAP, mix_JANN, mix_JANZ, mix_JANP, +  mix_JAE, mix_JAO,    mix_J1N, mix_J1Z, mix_J1P, mix_J1NN, mix_J1NZ, mix_J1NP,    mix_J2N, mix_J2Z, mix_J2P, mix_J2NN, mix_J2NZ, mix_J2NP,    mix_J3N, mix_J3Z, mix_J3P, mix_J3NN, mix_J3NZ, mix_J3NP, @@ -63,6 +64,7 @@ typedef enum {    mix_J5N, mix_J5Z, mix_J5P, mix_J5NN, mix_J5NZ, mix_J5NP,    mix_J6N, mix_J6Z, mix_J6P, mix_J6NN, mix_J6NZ, mix_J6NP,    mix_JXN, mix_JXZ, mix_JXP, mix_JXNN, mix_JXNZ, mix_JXNP, +  mix_JXE, mix_JXO,    mix_INCA, mix_DECA, mix_ENTA, mix_ENNA,    mix_INC1, mix_DEC1, mix_ENT1, mix_ENN1,    mix_INC2, mix_DEC2, mix_ENT2, mix_ENN2, diff --git a/mixlib/mix_types.c b/mixlib/mix_types.c index 46e87a2..4dac3ba 100644 --- a/mixlib/mix_types.c +++ b/mixlib/mix_types.c @@ -463,6 +463,40 @@ mix_word_shift_right_circular (mix_word_t A, mix_word_t X, gulong count,        | ( mix_word_magnitude (A1) >> c ) | ( MIX_WORD_MAX & (X1 << (30 - c)) );  } +void +mix_word_shift_left_binary (mix_word_t A, mix_word_t X, gulong count, +                            mix_word_t *pA, mix_word_t *pX) +{ +  if ( pX != NULL ) *pX = mix_word_sign (X); +  if ( pA != NULL ) *pA = mix_word_sign (A); +  if (count < 30) { +    if ( pX != NULL ) *pX |= MIX_WORD_MAX & (X << count); +    if ( pA != NULL ) +      *pA |= MIX_WORD_MAX & ( (A << count) | +			      (mix_word_magnitude (X) >> (30 - count)) ); +  } else if (count < 60 && pA != NULL) +    *pA |= MIX_WORD_MAX & (X << (count - 30)); +  else +    ; +} + +void +mix_word_shift_right_binary (mix_word_t A, mix_word_t X, gulong count, +                             mix_word_t *pA, mix_word_t *pX) +{ +  if ( pX != NULL ) *pX = mix_word_sign (X); +  if ( pA != NULL ) *pA = mix_word_sign (A); +  if (count < 30) { +    if ( pA != NULL ) +      *pA |= mix_word_magnitude (A) >> count; +    if ( pX != NULL ) +      *pX |= MIX_WORD_MAX & ( (mix_word_magnitude (X) >> count) +			      | (A << (30 - count)) ); +  } else if (count < 60 && pX != NULL) +    *pX |= mix_word_magnitude (A) >> (count - 30); +  else +    ; +}  /* Printable representation */  void diff --git a/mixlib/mix_types.h b/mixlib/mix_types.h index 9473b00..8bea145 100644 --- a/mixlib/mix_types.h +++ b/mixlib/mix_types.h @@ -136,6 +136,8 @@ mix_word_set_byte(mix_word_t *into,   /* word to be modified */  #define mix_word_magnitude(word)     ( (word) & (MIX_WORD_SIGN_BIT - 1) )  #define mix_word_is_positive(word)   ( mix_word_sign(word) == 0 )  #define mix_word_is_negative(word)   ( mix_word_sign(word) != 0 ) +#define mix_word_is_even(word)       ( ((word) & 1) == 0 ) +#define mix_word_is_odd(word)        ( ((word) & 1) == 1 )  /* Arithmetic operations */ @@ -175,10 +177,15 @@ mix_word_shift_left_circular(mix_word_t A, mix_word_t X, gulong count,  			     mix_word_t *pA, mix_word_t *pX);  extern void  mix_word_shift_right_circular(mix_word_t A, mix_word_t X, gulong count, -			     mix_word_t *pA, mix_word_t *pX); - +                              mix_word_t *pA, mix_word_t *pX); +extern void +mix_word_shift_left_binary(mix_word_t A, mix_word_t X, gulong count, +                           mix_word_t *pA, mix_word_t *pX); +extern void +mix_word_shift_right_binary(mix_word_t A, mix_word_t X, gulong count, +                            mix_word_t *pA, mix_word_t *pX);  /*   * Fields within a word: a word containing the (L:R) diff --git a/mixlib/testsuite/mix_vm_ins_t.c b/mixlib/testsuite/mix_vm_ins_t.c index 458cbba..1d368a7 100644 --- a/mixlib/testsuite/mix_vm_ins_t.c +++ b/mixlib/testsuite/mix_vm_ins_t.c @@ -245,6 +245,23 @@ test_shift_(mix_vm_t *vm, mix_dump_context_t *dc)    test.rA_a = mix_word_new_b(0,6,7,8,3);    test.rX_a = mix_word_new_bn(4,0,0,5,0);    run_test_(&test, vm, dc); + +  mix_ins_fill_from_id(ins, mix_SLB); +  ins.index = 0; +  ins.address = 3; +  fill_test_desc_(&test, vm, &ins); +  test.rA_b = mix_word_new(06543217654); +  test.rX_b = mix_word_new(03217654321); +  test.rA_a = mix_word_new(05432176543); +  test.rX_a = mix_word_new(02176543210); +  run_test_(&test, vm, dc); + +  mix_ins_fill_from_id(ins, mix_SRB); +  ins.address = 6; +  fill_test_desc_(&test, vm, &ins); +  test.rA_a = mix_word_new(00054321765); +  test.rX_a = mix_word_new(04321765432); +  run_test_(&test, vm, dc);  }  static void diff --git a/mixlib/xmix_vm.c b/mixlib/xmix_vm.c index 0f1104a..cf20ee1 100644 --- a/mixlib/xmix_vm.c +++ b/mixlib/xmix_vm.c @@ -188,6 +188,14 @@ sla_handler_ (mix_vm_t *vm, const mix_ins_t *ins)      mix_word_shift_right_circular (get_rA_ (vm), get_rX_ (vm), n,                                     &get_rA_ (vm), &get_rX_ (vm));      break; +  case mix_SLB: +    mix_word_shift_left_binary (get_rA_ (vm), get_rX_ (vm), n, +                                &get_rA_ (vm), &get_rX_ (vm)); +    break; +  case mix_SRB: +    mix_word_shift_right_binary (get_rA_ (vm), get_rX_ (vm), n, +                                 &get_rA_ (vm), &get_rX_ (vm)); +    break;    default:      fail_unexpected_ (vm);    } @@ -481,6 +489,12 @@ jpx_handler_ (mix_vm_t *vm, const mix_ins_t *ins)      jump = mix_word_magnitude (val) == MIX_WORD_ZERO        || mix_word_is_negative (val);      break; +  case mix_JAE: case mix_JXE: +    jump = mix_word_is_even (val); +    break; +  case mix_JAO: case mix_JXO: +    jump = mix_word_is_odd (val); +    break;    default:      fail_unexpected_ (vm);    }  | 
