Last active
January 29, 2019 06:53
-
-
Save momvart/a75205f954733bda2bc2a79f7e91940d to your computer and use it in GitHub Desktop.
MIPS assembly code that converts epoch to date and time parts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#MIPS equivalent of .NET DateTime.GetDatePart | |
#https://referencesource.microsoft.com/mscorlib/R/ff06f271f088f1a8.html | |
.macro push(%value) | |
addi $sp, $sp, -4 | |
sw %value, 0($sp) | |
.end_macro | |
.macro pop(%storeTo) | |
lw %storeTo, 0($sp) | |
addi $sp ,$sp, 4 | |
.end_macro | |
.macro lwmem(%reg, %label) | |
la $t7, %label | |
lw %reg, 0($t7) | |
.end_macro | |
.macro swmem(%reg, %label) | |
la $t7, %label | |
sw %reg, 0($t7) | |
.end_macro | |
.data | |
#Date Constants | |
DaysPerYear: .word 365 | |
DaysPer4Year: .word 1461 | |
DaysPer100Year: .word 36524 | |
DaysPer400Year: .word 146097 | |
DaysTo1970: .word 719162 | |
SecondsPerDay: .word 86400 | |
SecondsPerHour: .word 3600 | |
SecondsPerMinute: .word 60 | |
DaysTillMonths365: .word 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 | |
DaysTillMonths366: .word 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 | |
#Date Parts | |
curDateYear: .word 0 | |
curDateMonth: .word 0 | |
curDateDay: .word 0 | |
curDateHour: .word 0 | |
curDateMin: .word 0 | |
curDateSec: .word 0 | |
convertEpoch: #Extracts date parts from epoch timestamp. $a0: epoch | |
push($ra) | |
push($s0) | |
push($s1) | |
push($s2) | |
push($s3) | |
push($s4) | |
push($s5) | |
push($s6) | |
lwmem($t0, SecondsPerDay) | |
div $a0, $t0 | |
mfhi $s0 #remaining seconds for time of day | |
mflo $s1 #days in $s1 | |
bgez $s0, posPart1 | |
add $s0, $s0, $t0 | |
subi $s1, $s1, 1 | |
posPart1: | |
lwmem($t0, SecondsPerHour) | |
div $s0, $t0 #count of hours | |
mfhi $s0 | |
mflo $t0 | |
swmem($t0, curDateHour) | |
lwmem($t0, SecondsPerMinute) | |
div $s0, $t0 #count of minutes | |
mfhi $s0 | |
mflo $t0 | |
swmem($t0, curDateMin) | |
swmem($s0, curDateSec) #now $s0 is free | |
lwmem($t0, DaysTo1970) | |
add $s1, $t0, $s1 #moving to 0001/01/01 | |
lwmem($t0, DaysPer400Year) | |
div $s1, $t0 | |
mfhi $s1 | |
mflo $s2 #count of 400 years in y400 = $s2 | |
mul $s0, $s2, 400 #total years count will be stored in $s0 | |
posPart2: | |
lwmem($t0, DaysPer100Year) | |
div $s1, $t0 | |
mflo $s3 #count of 100 years in y100 = $s3 | |
bne $s3, 4, continue100 #if(y100 == 4) | |
li $s3, 3 #y100 = 3 | |
continue100: | |
mul $t0, $s3, $t0 #n -= y100 * DaysPer100Year | |
sub $s1, $s1, $t0 | |
mul $t0, $s3, 100 #years += y100 * 100 | |
add $s0, $t0, $s0 | |
lwmem($t0, DaysPer4Year) | |
div $s1, $t0 | |
mflo $s4 #count of 4 years in y4 = $s2 | |
continue4: | |
mul $t0, $s4, $t0 #n -= y4 * DaysPer4Year | |
sub $s1, $s1, $t0 | |
mul $t0, $s4, 4 | |
add $s0, $t0, $s0 #years += y4 * 4 | |
lwmem($t0, DaysPerYear) | |
div $s1, $t0 | |
mflo $s5 #count of years in y1 = $s5 | |
bne $s5, 4, continue1 #if(y1 == 4) | |
li $s5, 3 #y1 = 3 | |
continue1: | |
mul $t0, $s5, $t0 #n -= y1 * DaysPerYear | |
sub $s1, $s1, $t0 | |
add $s0, $s5, $s0 #years += y1 | |
addi $s0, $s0, 1 | |
swmem($s0, curDateYear) | |
#leapYear = y1 == 3 && (y4 != 24 || y100 == 3) | |
beq $s5, 3, leapYear1 | |
li $s6, 0 | |
j leapYear5 | |
leapYear1: | |
beq $s4, 24, leapYear2 | |
li $s6, 1 | |
j leapYear5 | |
leapYear2: | |
bne $s3, 3, leapYear3 | |
li $s6, 1 | |
j leapYear5 | |
leapYear3: | |
li $s6, 0 #leapYear is stored at $s6 | |
leapYear5: | |
beqz $s6, nonLeapCalc #if(leapYear) | |
la $s3, DaysTillMonths366 #$s3 = &DaysTillMonth366 | |
nonLeapCalc: #else | |
la $s3, DaysTillMonths365 #$s3 = &DaysTillMonth365 | |
sra $s2, $s1, 5 #m = n >> 5 + 1 | |
addi $s2, $s2, 1 | |
findMonthLoop: #while(n >= $s3[m]) | |
sll $t0, $s2, 2 | |
add $t0, $s3, $t0 | |
lw $t0, 0($t0) | |
blt $s1, $t0, findMonthLoopEnd | |
inc($s2) #m++ | |
j findMonthLoop | |
findMonthLoopEnd: | |
swmem($s2, curDateMonth) | |
subi $t1, $s2, 1 #days(in month) = n - $s3[m - 1] + 1 | |
sll $t1, $t1, 2 | |
add $t0, $t1, $s3 | |
lw $t0, 0($t0) | |
sub $t0, $s1, $t0 | |
addi $t0, $t0, 1 | |
swmem($t0, curDateDay) | |
pop($s6) | |
pop($s5) | |
pop($s4) | |
pop($s3) | |
pop($s2) | |
pop($s1) | |
pop($s0) | |
pop($ra) | |
jr $ra |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment