Home | History | Annotate | Download | only in math
      1 /*
      2  * Copyright 2015, Cyril Bur, IBM Corp.
      3  *
      4  * This program is free software; you can redistribute it and/or
      5  * modify it under the terms of the GNU General Public License
      6  * as published by the Free Software Foundation; either version
      7  * 2 of the License, or (at your option) any later version.
      8  */
      9 
     10 #include "basic_asm.h"
     11 #include "vmx_asm.h"
     12 
     13 # Should be safe from C, only touches r4, r5 and v0,v1,v2
     14 FUNC_START(check_vmx)
     15 	PUSH_BASIC_STACK(32)
     16 	mr r4,r3
     17 	li	r3,1 # assume a bad result
     18 	li	r5,0
     19 	lvx	v0,r5,r4
     20 	vcmpequd.	v1,v0,v20
     21 	vmr	v2,v1
     22 
     23 	addi	r5,r5,16
     24 	lvx	v0,r5,r4
     25 	vcmpequd.	v1,v0,v21
     26 	vand	v2,v2,v1
     27 
     28 	addi	r5,r5,16
     29 	lvx	v0,r5,r4
     30 	vcmpequd.	v1,v0,v22
     31 	vand	v2,v2,v1
     32 
     33 	addi	r5,r5,16
     34 	lvx	v0,r5,r4
     35 	vcmpequd.	v1,v0,v23
     36 	vand	v2,v2,v1
     37 
     38 	addi	r5,r5,16
     39 	lvx	v0,r5,r4
     40 	vcmpequd.	v1,v0,v24
     41 	vand	v2,v2,v1
     42 
     43 	addi	r5,r5,16
     44 	lvx	v0,r5,r4
     45 	vcmpequd.	v1,v0,v25
     46 	vand	v2,v2,v1
     47 
     48 	addi	r5,r5,16
     49 	lvx	v0,r5,r4
     50 	vcmpequd.	v1,v0,v26
     51 	vand	v2,v2,v1
     52 
     53 	addi	r5,r5,16
     54 	lvx	v0,r5,r4
     55 	vcmpequd.	v1,v0,v27
     56 	vand	v2,v2,v1
     57 
     58 	addi	r5,r5,16
     59 	lvx	v0,r5,r4
     60 	vcmpequd.	v1,v0,v28
     61 	vand	v2,v2,v1
     62 
     63 	addi	r5,r5,16
     64 	lvx	v0,r5,r4
     65 	vcmpequd.	v1,v0,v29
     66 	vand	v2,v2,v1
     67 
     68 	addi	r5,r5,16
     69 	lvx	v0,r5,r4
     70 	vcmpequd.	v1,v0,v30
     71 	vand	v2,v2,v1
     72 
     73 	addi	r5,r5,16
     74 	lvx	v0,r5,r4
     75 	vcmpequd.	v1,v0,v31
     76 	vand	v2,v2,v1
     77 
     78 	li	r5,STACK_FRAME_LOCAL(0,0)
     79 	stvx	v2,r5,sp
     80 	ldx	r0,r5,sp
     81 	cmpdi	r0,0xffffffffffffffff
     82 	bne	1f
     83 	li	r3,0
     84 1:	POP_BASIC_STACK(32)
     85 	blr
     86 FUNC_END(check_vmx)
     87 
     88 # Safe from C
     89 FUNC_START(test_vmx)
     90 	# r3 holds pointer to where to put the result of fork
     91 	# r4 holds pointer to the pid
     92 	# v20-v31 are non-volatile
     93 	PUSH_BASIC_STACK(512)
     94 	std	r3,STACK_FRAME_PARAM(0)(sp) # Address of varray
     95 	std r4,STACK_FRAME_PARAM(1)(sp) # address of pid
     96 	PUSH_VMX(STACK_FRAME_LOCAL(2,0),r4)
     97 
     98 	bl load_vmx
     99 	nop
    100 
    101 	li	r0,__NR_fork
    102 	sc
    103 	# Pass the result of fork back to the caller
    104 	ld	r9,STACK_FRAME_PARAM(1)(sp)
    105 	std	r3,0(r9)
    106 
    107 	ld r3,STACK_FRAME_PARAM(0)(sp)
    108 	bl check_vmx
    109 	nop
    110 
    111 	POP_VMX(STACK_FRAME_LOCAL(2,0),r4)
    112 	POP_BASIC_STACK(512)
    113 	blr
    114 FUNC_END(test_vmx)
    115 
    116 # int preempt_vmx(vector int *varray, int *threads_starting, int *running)
    117 # On starting will (atomically) decrement threads_starting as a signal that
    118 # the VMX have been loaded with varray. Will proceed to check the validity of
    119 # the VMX registers while running is not zero.
    120 FUNC_START(preempt_vmx)
    121 	PUSH_BASIC_STACK(512)
    122 	std r3,STACK_FRAME_PARAM(0)(sp) # vector int *varray
    123 	std r4,STACK_FRAME_PARAM(1)(sp) # int *threads_starting
    124 	std r5,STACK_FRAME_PARAM(2)(sp) # int *running
    125 	# VMX need to write to 16 byte aligned addresses, skip STACK_FRAME_LOCAL(3,0)
    126 	PUSH_VMX(STACK_FRAME_LOCAL(4,0),r4)
    127 
    128 	bl load_vmx
    129 	nop
    130 
    131 	sync
    132 	# Atomic DEC
    133 	ld r3,STACK_FRAME_PARAM(1)(sp)
    134 1:	lwarx r4,0,r3
    135 	addi r4,r4,-1
    136 	stwcx. r4,0,r3
    137 	bne- 1b
    138 
    139 2:	ld r3,STACK_FRAME_PARAM(0)(sp)
    140 	bl check_vmx
    141 	nop
    142 	cmpdi r3,0
    143 	bne 3f
    144 	ld r4,STACK_FRAME_PARAM(2)(sp)
    145 	ld r5,0(r4)
    146 	cmpwi r5,0
    147 	bne 2b
    148 
    149 3:	POP_VMX(STACK_FRAME_LOCAL(4,0),r4)
    150 	POP_BASIC_STACK(512)
    151 	blr
    152 FUNC_END(preempt_vmx)
    153