
	.requ	one,r11  	;; 1 is so important we keep it in a register
	mov	one,#1

;;
;;  }
;;}
;;
;;// Takes a pre-initialized array of numeric values and sort them using heapsort
;;int main( ) {
;;  int p;
;;
	.requ	p,r10           ; loop index variable
	.requ	remaining,r9    ; elements remaining in heap
	.requ	temp,r8         ; temp for swap

;;  // HEAP SORT!
;;
	ldr	p,valcVar
firstPass:
;;  for ( p = valc - 1; 0 <= p; p-- ) {
	subs	p,p,#1     	; this combines -- from start and end of loop
	adrlt	pc,firstPassEnd

;;    heapify( values, p, valc );
	adr	r1,valuesArray
	mov	r2,p
	ldr	r3,valcVar
	adr	lr,firstPass    ; pass start of loop as return address
	adr	pc,heapify
	
;;  }
firstPassEnd:	
;;
;;  int remaining = valc;
	ldr	remaining,valcVar
secondPass:	
;;  while ( remaining > 0 ) {
	movs	remaining,remaining
	adrle	pc,secondPassEnd
	
;;    remaining--;
	sub	remaining,remaining,#1
	
;;    int temp = values[0];
	ldr	temp,valuesArray

;;    value[0] = values[remaining];
	adr	r12,valuesArray
	orr	r12,r12,remaining    ; can use orr in place of add
                                     ; because array address is 2^6
	ldr	r1,[r12,#0]
	str	r1,valuesArray

;;    values[remaining] = temp;
	str	temp,[r12,#0]

;;    heapify( values, 0, remaining );
	adr	r1,valuesArray
	mov	r2,#0
	mov	r3,remaining
	adr	lr,secondPass	; pass loop start as return address
	adr	pc,heapify	

;;  }
secondPassEnd:	

;;      HALT IN INFINITE LOOP
	add	pc,pc,#0
;;}



;;
;;void heapify( int values[], int rootIndex, int heapSize ) {
heapify:
	sub	sp,sp,#1
	str	lr,[sp,#0]

	.requ	values,r1
	.requ	rootIndex,r2
	.requ   heapSize,r3
	
	.requ	smallestChild,r4
	.requ	sibling,r5
;;  int smallestChild = 2*rootIndex + 1;

	add	smallestChild,one,rootIndex,asl #1
;;
;;  while ( smallestChild < heapSize ) { 
heapifyLoop:
	subs	r12,smallestChild,heapSize
	adrge	pc,return

;;    int sibling = smallestChild + 1;
	add	sibling,smallestChild,#1	

;;    if ( sibling < heapSize &&
	subs	r12,sibling,heapSize
	adrge	pc,keepChild
;;         values[ sibling ] < values[ smallestChild ] ) {
	mov	r12,values
	add	r12,r12,sibling
	ldr	r12,[r12,#0]

	mov	r6,values
	add	r6,r6,smallestChild
	ldr	r6,[r6,#0]
	subs	r12,r12,r6

;;      smallestChild = sibling;
	movlt	smallestChild,sibling
;;    }
keepChild:
;;
;;    if ( values[rootIndex] < values[smallestChild] ) {
	mov	r12,values	
	add	r12,r12,rootIndex
	ldr	r12,[r12,#0]

	mov	r6,values
	add	r6,r6,smallestChild
	ldr	r6,[r6,#0]

	subs	r6,r12,r6
	sublt	sp,sp,#1
	ldrlt	pc,[sp,#1]
;;      return;
;;
;;    } else {
;;      int temp = values[rootIndex];
	;   r12 is already temp

;;	values[rootIndex] = values[smallestChild];
	mov	r6,values
	add	r6,r6,smallestChild
	ldr	r5,[r6,#0]
	str	r12,[r6,#0]
	
;;      values[smallestChild] = temp;
	mov	r12,values
	add	r12,r12,rootIndex
	str	r5,[r12,#0]
	

;;      rootIndex = smallestChild;
	mov	rootIndex,smallestChild

;;      smallestChild = 2*rootIndex + 1;
	add	smallestChild,one,rootIndex,asl #1

;;    }
	adr	pc,heapifyLoop
return:
	sub	sp,sp,#1
	ldr	pc,[sp,#1]
	
;;// The values to be sorted
;;int values[20];
	.origin 128   		; ensure array address has 6 trailing 0's
valuesArray:
	.data 4, 9, 1, 6, 11, 2, 7, 3, 5, 8, 10
;;
;;// How many values are in the values array
;;int valc;
;;
valcVar:
	.data 11
