# New Ticket Created by  Nick Glencross 
# Please include the string:  [perl #29246]
# in the subject line of all future correspondence about this issue. 
# <URL: http://rt.perl.org:80/rt3/Ticket/Display.html?id=29246 >


While creating a test script for Digest_MD5.imc (attached, and should be 
placed in runtime/parrot/include), I came across this segfault. I've 
attached a culprit script.

The gdb backtrace looks like this:

(gdb) where
#0  0x4003c510 in pthread_getconcurrency () from /lib/libpthread.so.0
#1  0xbffff408 in ?? ()
#2  0x4003c36f in pthread_getconcurrency () from /lib/libpthread.so.0
#3  0x4003baa1 in pthread_create () from /lib/libpthread.so.0
#4  0x080de463 in init_events_first (interpreter=0x829b050) at 
src/events.c:265
#5  0x080de5a4 in Parrot_init_events (interpreter=0x829b050)
    at src/events.c:309
#6  0x08094bfa in make_interpreter (parent=0x0, flags=NO_FLAGS)
    at src/interpreter.c:1827
#7  0x080d3423 in Parrot_new (parent=0x0) at src/embed.c:47
#8  0x08092455 in main (argc=2, argv=0xbffff674) at imcc/main.c:409
#9  0x401c0cb1 in __libc_start_main () from /lib/libc.so.6
(gdb)

Line 265 of src/events.c is 'THREAD_CREATE_DETACHED(ev_handle, 
event_thread, event_queue);'

Removing lines from the test (especially the long one at the bottom) 
will make the problem go away.

Regards,

Nick
      .sub _main
             $P0 = _md5sum ("0")
             _md5_print ($P0)
              


             $P0 = _md5sum ("01")
             _md5_print ($P0)
              


             $P0 = _md5sum ("012")
             _md5_print ($P0)
              


             $P0 = _md5sum ("0123")
             _md5_print ($P0)
              


             $P0 = _md5sum ("01234")
             _md5_print ($P0)
              


             $P0 = _md5sum ("012345")
             _md5_print ($P0)
              


             $P0 = _md5sum ("0123456")
             _md5_print ($P0)
              


             $P0 = _md5sum ("01234567")
             _md5_print ($P0)
              


             $P0 = _md5sum ("012345678")
             _md5_print ($P0)
              


             $P0 = _md5sum ("0123456789")
             _md5_print ($P0)
              


             $P0 = _md5sum ("01234567890")
             _md5_print ($P0)
              


             $P0 = _md5sum ("012345678901")
             _md5_print ($P0)
              


             $P0 = _md5sum ("0123456789012")
             _md5_print ($P0)
              


             $P0 = _md5sum ("01234567890123")
             _md5_print ($P0)
              


             $P0 = _md5sum ("012345678901234")
             _md5_print ($P0)
              


             $P0 = _md5sum ("0123456789012345")
             _md5_print ($P0)
              


             $P0 = _md5sum ("01234567890123456")
             _md5_print ($P0)
              


             $P0 = _md5sum ("012345678901234567")
             _md5_print ($P0)
              


             $P0 = _md5sum ("0123456789012345678")
             _md5_print ($P0)
              


             $P0 = _md5sum ("01234567890123456789")
             _md5_print ($P0)
              


             $P0 = _md5sum ("012345678901234567890")
             _md5_print ($P0)
              


             $P0 = _md5sum ("0123456789012345678901")
             _md5_print ($P0)
              


             $P0 = _md5sum ("01234567890123456789012")
             _md5_print ($P0)
              


             $P0 = _md5sum ("012345678901234567890123")
             _md5_print ($P0)
              


             $P0 = _md5sum ("0123456789012345678901234")
             _md5_print ($P0)
              


             $P0 = _md5sum ("01234567890123456789012345")
             _md5_print ($P0)
              


             $P0 = _md5sum ("012345678901234567890123456")
             _md5_print ($P0)
              


             $P0 = _md5sum ("0123456789012345678901234567")
             _md5_print ($P0)
              


             $P0 = _md5sum ("01234567890123456789012345678")
             _md5_print ($P0)
              


             $P0 = _md5sum ("012345678901234567890123456789")
             _md5_print ($P0)
              


             $P0 = _md5sum ("0123456789012345678901234567890")
             _md5_print ($P0)
              


             $P0 = _md5sum ("01234567890123456789012345678901")
             _md5_print ($P0)
              


             $P0 = _md5sum ("012345678901234567890123456789012")
             _md5_print ($P0)
              


             $P0 = _md5sum ("0123456789012345678901234567890123")
             _md5_print ($P0)
              


             $P0 = _md5sum ("01234567890123456789012345678901234")
             _md5_print ($P0)
              


             $P0 = _md5sum ("012345678901234567890123456789012345")
             _md5_print ($P0)
              


             $P0 = _md5sum ("0123456789012345678901234567890123456")
             _md5_print ($P0)
              


             $P0 = _md5sum ("01234567890123456789012345678901234567")
             _md5_print ($P0)
              


             $P0 = _md5sum ("012345678901234567890123456789012345678")
             _md5_print ($P0)
              


             $P0 = _md5sum ("0123456789012345678901234567890123456789")
             _md5_print ($P0)
              


             $P0 = _md5sum ("01234567890123456789012345678901234567890")
             _md5_print ($P0)
              


             $P0 = _md5sum ("012345678901234567890123456789012345678901")
             _md5_print ($P0)
              


             $P0 = _md5sum ("0123456789012345678901234567890123456789012")
             _md5_print ($P0)
              


             $P0 = _md5sum ("01234567890123456789012345678901234567890123")
             _md5_print ($P0)
              


             $P0 = _md5sum ("012345678901234567890123456789012345678901234")
             _md5_print ($P0)
              


             $P0 = _md5sum ("0123456789012345678901234567890123456789012345")
             _md5_print ($P0)
              


             $P0 = _md5sum ("01234567890123456789012345678901234567890123456")
             _md5_print ($P0)
              


             $P0 = _md5sum ("012345678901234567890123456789012345678901234567")
             _md5_print ($P0)
              


             $P0 = _md5sum ("0123456789012345678901234567890123456789012345678")
             _md5_print ($P0)
              


             $P0 = _md5sum ("01234567890123456789012345678901234567890123456789")
             _md5_print ($P0)
              


             $P0 = _md5sum ("012345678901234567890123456789012345678901234567890")
             _md5_print ($P0)
              


             $P0 = _md5sum ("0123456789012345678901234567890123456789012345678901")
             _md5_print ($P0)
              


             $P0 = _md5sum ("01234567890123456789012345678901234567890123456789012")
             _md5_print ($P0)
              


             $P0 = _md5sum ("012345678901234567890123456789012345678901234567890123")
             _md5_print ($P0)
              


             $P0 = _md5sum ("0123456789012345678901234567890123456789012345678901234")
             _md5_print ($P0)
              


             $P0 = _md5sum ("01234567890123456789012345678901234567890123456789012345")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("012345678901234567890123456789012345678901234567890123456")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("0123456789012345678901234567890123456789012345678901234567")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("01234567890123456789012345678901234567890123456789012345678")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("012345678901234567890123456789012345678901234567890123456789")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("0123456789012345678901234567890123456789012345678901234567890")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("01234567890123456789012345678901234567890123456789012345678901")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("012345678901234567890123456789012345678901234567890123456789012")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("0123456789012345678901234567890123456789012345678901234567890123")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("01234567890123456789012345678901234567890123456789012345678901234")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("012345678901234567890123456789012345678901234567890123456789012345")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("0123456789012345678901234567890123456789012345678901234567890123456")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("01234567890123456789012345678901234567890123456789012345678901234567")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("012345678901234567890123456789012345678901234567890123456789012345678")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("0123456789012345678901234567890123456789012345678901234567890123456789")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("01234567890123456789012345678901234567890123456789012345678901234567890")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("012345678901234567890123456789012345678901234567890123456789012345678901")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("0123456789012345678901234567890123456789012345678901234567890123456789012")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("01234567890123456789012345678901234567890123456789012345678901234567890123")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("012345678901234567890123456789012345678901234567890123456789012345678901234")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("0123456789012345678901234567890123456789012345678901234567890123456789012345")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("01234567890123456789012345678901234567890123456789012345678901234567890123456")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("012345678901234567890123456789012345678901234567890123456789012345678901234567")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("0123456789012345678901234567890123456789012345678901234567890123456789012345678")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("01234567890123456789012345678901234567890123456789012345678901234567890123456789")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("012345678901234567890123456789012345678901234567890123456789012345678901234567890")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("0123456789012345678901234567890123456789012345678901234567890123456789012345678901")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("01234567890123456789012345678901234567890123456789012345678901234567890123456789012")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("012345678901234567890123456789012345678901234567890123456789012345678901234567890123")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("0123456789012345678901234567890123456789012345678901234567890123456789012345678901234")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("01234567890123456789012345678901234567890123456789012345678901234567890123456789012345")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("012345678901234567890123456789012345678901234567890123456789012345678901234567890123456")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890")
             _md5_print ($P0)
              


             $P0 = _md5sum 
("012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890")
             _md5_print ($P0)
              

      end
     .end

      .include "runtime/parrot/include/Digest_MD5.imc"
# Parrot md5sum; Nick Glencross <[EMAIL PROTECTED]>
#
# Based on md5.c, from md5sum
#           written by Ulrich Drepper <[EMAIL PROTECTED]>, 1995.

=head1 NAME

Digest_MD5.imc - calculate MD5 checksums

=head1 SYNOPSIS

See examples/assembly/md5sum.imc

=head1 DESCRIPTION

This is a pure Parrot MD5 hash routine.

=head1 SUBROUTINES

=head2 _md5sum

Pass in a string, returns a PMC Array with the result

=head2 _md5_print

Pass it the PMC array to print the checksum.

=head1 BUGS

Only tested so far on i386.

=over 4

=item * Might work on 64 bit platforms

=item * Might not work on big endian systems

=back

=cut

###########################################################################
# Main entry point

.sub _md5sum
     .param string str

     $P0 = _config()

     $I0 = $P0["intsize"]
     if $I0 == 4 goto is_4byte_word

     printerr "This doesn't seem to be a 32 bit processor: "
     printerr "Please verify the MD5 checksum\n"

is_4byte_word:

     $I0 = $P0["bigendian"]

     unless $I0 goto is_little_endian

     printerr "This appears to be a big endian processor: "
     printerr "Please verify the MD5 checksum\n"

is_little_endian:

     .local Array buffer
     buffer = new Array
    
     $P0 = new Array
     $P0 = 4

     _md5_create_buffer (str, buffer, $I0)

     # _print_buffer (buffer, 8)

     _md5_init ($P0)
     _md5_process_buffer ($P0, buffer)

     .pcc_begin_return
       .return $P0
     .pcc_end_return
.end

 .include "library/config.imc"

###########################################################################
# Low-level macros used in MD5

# A parrot rol instruction might be good (as it can often be JIT'd)
.macro rol (x,n,  out)
     shl .out, .x, .n 
     $I1000 = 32-.n
     $I1000 = .x >>> $I1000
     $I1000 = $I1000 & 0xffffffff
     bor .out, $I1000
.endm

.macro FF (b,c,d)
     tmp = .c ~ .d
     tmp = .b & tmp
     tmp = .d ~ tmp
.endm

.macro FH (b,c,d)
     tmp = .b ~ .c
     tmp = tmp ~ .d
.endm

.macro FI (b,c,d)
     tmp = ~.d
     tmp = .b | tmp
     tmp = .c ~ tmp
.endm

###########################################################################
# Higher level MD5 operations

.macro common (a, b, k, s, T)
     .a = .a + tmp
     .a = .a + .T
     tmp = buffer[.k]
     .a = .a + tmp
     .rol (.a, .s, tmp)
     .a = .b + tmp
.endm

.macro OP1 (aa,bb,cc,dd, kk, ss, TT)
     .FF (.bb,.cc,.dd)
     .common (.aa, .bb, .kk, .ss, .TT)
.endm

.macro OP2 (aa,bb,cc,dd, kk, ss, TT)
     .FF (.dd,.bb,.cc)
     .common (.aa, .bb, .kk, .ss, .TT)
.endm

.macro OP3 (aa,bb,cc,dd, kk, ss, TT)
     .FH (.bb,.cc,.dd)
     .common (.aa, .bb, .kk, .ss, .TT)
.endm

.macro OP4 (aa,bb,cc,dd, kk, ss, TT)
     .FI (.bb,.cc,.dd)
     .common (.aa, .bb, .kk, .ss, .TT)
.endm

###########################################################################

# Swap the bytes which make up a word

.macro swap (w)

     $I10 = .w & 0x000000ff
     $I11 = .w & 0x0000ff00
     $I12 = .w & 0x00ff0000
     $I13 = .w & 0xff000000

     $I10 = $I10 <<  24
     $I11 = $I11 <<  8
     $I12 = $I12 >>> 8
     $I13 = $I13 >>> 24

     $I10 = $I10 | $I11
     $I10 = $I10 | $I12
     .w   = $I10 | $I13

     # For 64-bit architectures
     .w   = .w & 0xffffffff

.endm

###########################################################################

# Set the initial MD5 constants

.sub _md5_init
     .param pmc context

     # Initial MD5 constants
     context[0] = 0x67452301
     context[1] = 0xefcdab89
     context[2] = 0x98badcfe
     context[3] = 0x10325476

.end

###########################################################################

# Create a buffer from the requested buffer

.sub _md5_create_buffer
     .param string str
     .param Array  buffer
     .param int endian

     .local int counter
     .local int subcounter
     .local int slow_counter

     .local int word

     $I0 = length str

     $I1 = $I0 - 1

     # Work out how many words to allocate
     .local int words
     words = $I0 + 8
     words = words | 63
     words = words + 1
     words = words / 4

     buffer = words

     word         = 0
     counter      = 0
     subcounter   = 0
     slow_counter = 0

md5_create_buffer_loop:     

     $I5 = counter + subcounter

     if $I5 > $I0 goto md5_create_buffer_break

     # MD5 pad character, which goes last
     $I4 = 0x80

     if $I5 > $I1 goto string_char
     $S0 = str[$I5]
     $I4 = ord $S0

string_char:

     word = word << 8
     word = word | $I4

     subcounter = subcounter + 1

     if subcounter != 4 goto md5_create_buffer_loop

     if endian goto endian_ok

     .swap (word)

endian_ok:


     buffer[slow_counter] = word

     word         = 0
     counter      = counter + 4
     subcounter   = 0
     slow_counter = slow_counter + 1

     goto md5_create_buffer_loop

md5_create_buffer_break:

     # Check for a partial word

     if subcounter == 0 goto complete

     subcounter = 4 - subcounter

     .local int shift
     shift = 8*subcounter

     word = word << shift

     if endian goto endian_ok2

     .swap (word)

endian_ok2:

     buffer[slow_counter] = word

complete:

     # The number of bits in the string go into the last two words
        
     $I1 = $I0 >>> 29
     words = words - 1
     buffer[words] = $I1

     $I0 = $I0 << 3
     $I0 = $I0 & 0xffffff
     words = words - 1
     buffer[words] = $I0

.end

###########################################################################

.sub _md5_process_buffer
     .param pmc    context
     .param Array  buffer

     .local int A
     .local int B
     .local int C
     .local int D

     .local int A_save
     .local int B_save
     .local int C_save
     .local int D_save

     .local int tmp

     $P0 = new Array

     A = context[0]
     B = context[1]
     C = context[2]
     D = context[3]

md5_loop:

     A_save = A
     B_save = B 
     C_save = C
     D_save = D

     # Round 1.
     .OP1 (A, B, C, D, 0,  7, 0xd76aa478)
     .OP1 (D, A, B, C, 1, 12, 0xe8c7b756)
     .OP1 (C, D, A, B, 2, 17, 0x242070db)
     .OP1 (B, C, D, A, 3, 22, 0xc1bdceee)
     .OP1 (A, B, C, D, 4,  7, 0xf57c0faf)
     .OP1 (D, A, B, C, 5, 12, 0x4787c62a)
     .OP1 (C, D, A, B, 6, 17, 0xa8304613)
     .OP1 (B, C, D, A, 7, 22, 0xfd469501)
     .OP1 (A, B, C, D, 8,  7, 0x698098d8)
     .OP1 (D, A, B, C, 9, 12, 0x8b44f7af)
     .OP1 (C, D, A, B, 10,17, 0xffff5bb1)
     .OP1 (B, C, D, A, 11,22, 0x895cd7be)
     .OP1 (A, B, C, D, 12, 7, 0x6b901122)
     .OP1 (D, A, B, C, 13,12, 0xfd987193)
     .OP1 (C, D, A, B, 14,17, 0xa679438e)
     .OP1 (B, C, D, A, 15,22, 0x49b40821)

     # Round 2.
     .OP2 (A, B, C, D,  1,  5, 0xf61e2562)
     .OP2 (D, A, B, C,  6,  9, 0xc040b340)
     .OP2 (C, D, A, B, 11, 14, 0x265e5a51)
     .OP2 (B, C, D, A,  0, 20, 0xe9b6c7aa)
     .OP2 (A, B, C, D,  5,  5, 0xd62f105d)
     .OP2 (D, A, B, C, 10,  9, 0x02441453)
     .OP2 (C, D, A, B, 15, 14, 0xd8a1e681)
     .OP2 (B, C, D, A,  4, 20, 0xe7d3fbc8)
     .OP2 (A, B, C, D,  9,  5, 0x21e1cde6)
     .OP2 (D, A, B, C, 14,  9, 0xc33707d6)
     .OP2 (C, D, A, B,  3, 14, 0xf4d50d87)
     .OP2 (B, C, D, A,  8, 20, 0x455a14ed)
     .OP2 (A, B, C, D, 13,  5, 0xa9e3e905)
     .OP2 (D, A, B, C,  2,  9, 0xfcefa3f8)
     .OP2 (C, D, A, B,  7, 14, 0x676f02d9)
     .OP2 (B, C, D, A, 12, 20, 0x8d2a4c8a)

     # Round 3.
     .OP3 (A, B, C, D,  5,  4, 0xfffa3942)
     .OP3 (D, A, B, C,  8, 11, 0x8771f681)
     .OP3 (C, D, A, B, 11, 16, 0x6d9d6122)
     .OP3 (B, C, D, A, 14, 23, 0xfde5380c)
     .OP3 (A, B, C, D,  1,  4, 0xa4beea44)
     .OP3 (D, A, B, C,  4, 11, 0x4bdecfa9)
     .OP3 (C, D, A, B,  7, 16, 0xf6bb4b60)
     .OP3 (B, C, D, A, 10, 23, 0xbebfbc70)
     .OP3 (A, B, C, D, 13,  4, 0x289b7ec6)
     .OP3 (D, A, B, C,  0, 11, 0xeaa127fa)
     .OP3 (C, D, A, B,  3, 16, 0xd4ef3085)
     .OP3 (B, C, D, A,  6, 23, 0x04881d05)
     .OP3 (A, B, C, D,  9,  4, 0xd9d4d039)
     .OP3 (D, A, B, C, 12, 11, 0xe6db99e5)
     .OP3 (C, D, A, B, 15, 16, 0x1fa27cf8)
     .OP3 (B, C, D, A,  2, 23, 0xc4ac5665)

     # Round 4.
     .OP4 (A, B, C, D,  0,  6, 0xf4292244)
     .OP4 (D, A, B, C,  7, 10, 0x432aff97)
     .OP4 (C, D, A, B, 14, 15, 0xab9423a7)
     .OP4 (B, C, D, A,  5, 21, 0xfc93a039)
     .OP4 (A, B, C, D, 12,  6, 0x655b59c3)
     .OP4 (D, A, B, C,  3, 10, 0x8f0ccc92)
     .OP4 (C, D, A, B, 10, 15, 0xffeff47d)
     .OP4 (B, C, D, A,  1, 21, 0x85845dd1)
     .OP4 (A, B, C, D,  8,  6, 0x6fa87e4f)
     .OP4 (D, A, B, C, 15, 10, 0xfe2ce6e0)
     .OP4 (C, D, A, B,  6, 15, 0xa3014314)
     .OP4 (B, C, D, A, 13, 21, 0x4e0811a1)
     .OP4 (A, B, C, D,  4,  6, 0xf7537e82)
     .OP4 (D, A, B, C, 11, 10, 0xbd3af235)
     .OP4 (C, D, A, B,  2, 15, 0x2ad7d2bb)
     .OP4 (B, C, D, A,  9, 21, 0xeb86d391)

     A += A_save
     B += B_save
     C += C_save
     D += D_save

     splice buffer, $P0, 0, 16
     $I0 = buffer

     if $I0 > 0 goto md5_loop

     context[0] = A
     context[1] = B
     context[2] = C
     context[3] = D
 
     # _print_vals (A,B,C,D)
     # print "\n"

.end

###########################################################################

# Print four hex values

.sub _print_vals
     .param int A
     .param int B
     .param int C
     .param int D

     $P0 = new Array
     $P0 = 4
     $P0[0] = A
     $P0[1] = B
     $P0[2] = C
     $P0[3] = D

     sprintf $S0, "%08lx%08lx%08lx%08lx", $P0
     print $S0
.end

###########################################################################

# Print the final checksum

.sub _md5_print
     .param Array context

     .local int A
     .local int B
     .local int C
     .local int D

     A = context[0]
     B = context[1]
     C = context[2]
     D = context[3]

     $P0 = _config()

     $I0 = $P0["bigendian"]

     if $I0 goto dont_swap

     .swap (A)
     .swap (B)
     .swap (C)
     .swap (D)

dont_swap:

     _print_vals (A,B,C,D)
.end

###########################################################################

# For debugging

.sub _print_buffer
     .param Array buffer
     .param int word_size

     .local int size

     size = buffer

     .local int counter
     .local int value

     counter = 0

print_buffer_loop:
     if counter >= size goto print_buffer_done
     value = buffer[counter]
     $S0 = _number_as_hex (value, word_size)
     print $S0
     print " | "
     counter = counter + 1
     goto print_buffer_loop
    
print_buffer_done:

     print "\n"
.end

###########################################################################

# Also for debugging

.sub _number_as_hex
     .param int number
     .param int word_size

      $P0 = new Array
      $P0 = 1
      $P0[0] = number

      $S1 = "%0"
      $S0 = word_size
      concat $S1, $S0 
      concat $S1, "lx"
 
      sprintf $S0, $S1, $P0

     .pcc_begin_return
      .return $S0
     .pcc_end_return
.end

Reply via email to