public
Created

The answer for the reddit daily programmer challenge 121 intermediate written in system 390 assembly. Note: will only run when malloc can pass.

  • Download Gist
c121intermediate.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
.section .text,"ax","progbits"
 
.file "foo.c"
.section .text
.align 4
 
.globl foo
 
.type foo,@function
foo:
.foo:
#GPR2 = size, GPR3 = buffer
STG GPR14,112(,GPR15)
STMG GPR7,GPR11,56(GPR15)
LA GPR1,0(,GPR15)
LAY GPR15,-160(,GPR15)
STG GPR1,-160(,GPR1)
#copy over new array pointer
LGR GPR7,GPR3
#calculate amount of room needed
LA GPR9,1(,GPR2)
LGR GPR11,GPR9
#store initial data
XGR GPR4,GPR4
STG GPR4,0(GPR7)
LA GPR4,1(,GPR0)
#do the computation in DP fashion, index = R4, count = R9, accume = R8, working regs = R2,R3,R5
_compute:
#load i/2
#shifts can be replaced with RISBG on newer machines
SRLG GPR3,GPR4,1(GPR0)
SLLG GPR3,GPR3,3(GPR0)
LG GPR8,0(GPR3,GPR7)
#load i/3
LGR GPR3,GPR4
XGR GPR2,GPR2
LA GPR5,3(,GPR0)
DLGR GPR2,GPR5 # GPR2:GPR3/GPR5 = GPR3 R GPR2
SLLG GPR3,GPR3,3(GPR0)
ALG GPR8,0(GPR3,GPR7)
#load i/4
SRLG GPR3,GPR4,2(GPR0)
SLLG GPR3,GPR3,3(GPR0)
ALG GPR8,0(GPR3,GPR7)
#compute the max early to avoid waits
CLGR GPR4,GPR8
#store sum at index
SLLG GPR3,GPR4,3(GPR0)
STG GPR8,0(GPR3,GPR7)
#overwrite max if needed
#would be so much more elegant if this machine supported STOCG
BRC 12,_skipstore
STG GPR4,0(GPR3,GPR7)
_skipstore:
#increment, compare, and branch
LA GPR4,1(,GPR4)
BRCT GPR9,_compute #subtract 1 then compare with 0, if equal don't branch
#load final answer
SLLG GPR3,GPR11,3(GPR0)
LG GPR2,0(GPR3,GPR7)
_end:
LMG GPR7,GPR11,216(GPR15)
LG GPR14,272(,GPR15)
LA GPR15,160(,GPR15)
BCR 0xf,GPR14
.Lfefoo:
.size foo,.Lfefoo-foo
.section .data
.align 8
$CONSTANT_AREA:
 
.align 4
.type __func___3,@object
.size __func___3,4
__func___3:
.long 0x666f6f00 # 0x00000000 foo.
main.c
C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/*#define INDEX_VAL 1000ULL*/
#define INDEX_VAL 10000000000ULL
extern unsigned long long int foo(unsigned long long int, unsigned long long int *);
 
int main()
{
unsigned long long int retval;
unsigned long long int *buffer;
buffer = (unsigned long long int *)malloc((INDEX_VAL + 1) * sizeof(unsigned long long int));
if(!buffer)
{
printf("Couldn't allocate buffer!\n");
return 1;
}
retval = foo(INDEX_VAL, buffer);
printf("%llu\n", retval);
free(buffer);
return 0;
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.