1*8469df92Sandvar/* $NetBSD: fpemu.S,v 1.8 2024/09/07 06:17:37 andvar Exp $ */ 2f4f0d8a3Sfredette 3f4f0d8a3Sfredette/* $OpenBSD: fpemu.S,v 1.4 2001/03/29 02:18:45 mickey Exp $ */ 4f4f0d8a3Sfredette 5f4f0d8a3Sfredette/* 632381fa0Ssnj * Copyright (c) 2000-2004 Michael Shalayeff 7f4f0d8a3Sfredette * All rights reserved. 8f4f0d8a3Sfredette * 9f4f0d8a3Sfredette * Redistribution and use in source and binary forms, with or without 10f4f0d8a3Sfredette * modification, are permitted provided that the following conditions 11f4f0d8a3Sfredette * are met: 12f4f0d8a3Sfredette * 1. Redistributions of source code must retain the above copyright 13f4f0d8a3Sfredette * notice, this list of conditions and the following disclaimer. 14f4f0d8a3Sfredette * 2. Redistributions in binary form must reproduce the above copyright 15f4f0d8a3Sfredette * notice, this list of conditions and the following disclaimer in the 16f4f0d8a3Sfredette * documentation and/or other materials provided with the distribution. 17f4f0d8a3Sfredette * 18f4f0d8a3Sfredette * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19f4f0d8a3Sfredette * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20f4f0d8a3Sfredette * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2132381fa0Ssnj * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, 2232381fa0Ssnj * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 2332381fa0Ssnj * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 2432381fa0Ssnj * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2532381fa0Ssnj * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 2632381fa0Ssnj * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 2732381fa0Ssnj * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 2832381fa0Ssnj * THE POSSIBILITY OF SUCH DAMAGE. 29f4f0d8a3Sfredette */ 30f4f0d8a3Sfredette 31f4f0d8a3Sfredette#include <machine/asm.h> 32f4f0d8a3Sfredette#include "assym.h" 33f4f0d8a3Sfredette 34f4f0d8a3Sfredette#define FPEMU_VERSION (1 << 11) 35f4f0d8a3Sfredette 36f4f0d8a3Sfredette#define FP_TABLE2(name, ep0, ep1, ep2, ep3) \ 3793a4f7c6Sskrll ldil L%L$fpemu_tbl$name, %t1 ! \ 3893a4f7c6Sskrll ldo R%L$fpemu_tbl$name(%t1), %t1 ! \ 3906332c88Schs ldwx,s %r1(%t1), %t2 ! \ 4006332c88Schs bv %r0(%t2) ! \ 41f4f0d8a3Sfredette nop ! \ 4293a4f7c6Sskrll .label L$fpemu_tbl$name ! \ 43f4f0d8a3Sfredette .import __CONCAT(__CONCAT(ep0,_),name), code ! \ 44f4f0d8a3Sfredette .import __CONCAT(__CONCAT(ep1,_),name), code ! \ 45f4f0d8a3Sfredette .import __CONCAT(__CONCAT(ep2,_),name), code ! \ 46f4f0d8a3Sfredette .import __CONCAT(__CONCAT(ep3,_),name), code ! \ 47f4f0d8a3Sfredette .word __CONCAT(__CONCAT(ep0,_),name), __CONCAT(__CONCAT(ep1,_),name), __CONCAT(__CONCAT(ep2,_),name), __CONCAT(__CONCAT(ep3,_),name) 48f4f0d8a3Sfredette 49f4f0d8a3Sfredette#define FP_TABLE3(name,ep0,ep1,ep2,ep3,ep4,ep5,ep6,ep7,ep8,ep9,epa,epb,epc,epd,epe,epf) \ 5093a4f7c6Sskrll ldil L%L$fpemu_tbl$name, %t1 ! \ 5193a4f7c6Sskrll ldo R%L$fpemu_tbl$name(%t1), %t1 ! \ 5206332c88Schs ldwx,s %r1(%t1), %t2 ! \ 5306332c88Schs bv %r0(%t2) ! \ 54f4f0d8a3Sfredette nop ! \ 5593a4f7c6Sskrll .label L$fpemu_tbl$name ! \ 56f4f0d8a3Sfredette .import __CONCAT(__CONCAT(ep0,_),name), code ! \ 57f4f0d8a3Sfredette .import __CONCAT(__CONCAT(ep1,_),name), code ! \ 58f4f0d8a3Sfredette .import __CONCAT(__CONCAT(ep2,_),name), code ! \ 59f4f0d8a3Sfredette .import __CONCAT(__CONCAT(ep3,_),name), code ! \ 60f4f0d8a3Sfredette .import __CONCAT(__CONCAT(ep4,_),name), code ! \ 61f4f0d8a3Sfredette .import __CONCAT(__CONCAT(ep5,_),name), code ! \ 62f4f0d8a3Sfredette .import __CONCAT(__CONCAT(ep6,_),name), code ! \ 63f4f0d8a3Sfredette .import __CONCAT(__CONCAT(ep7,_),name), code ! \ 64f4f0d8a3Sfredette .import __CONCAT(__CONCAT(ep8,_),name), code ! \ 65f4f0d8a3Sfredette .import __CONCAT(__CONCAT(ep9,_),name), code ! \ 66f4f0d8a3Sfredette .import __CONCAT(__CONCAT(epa,_),name), code ! \ 67f4f0d8a3Sfredette .import __CONCAT(__CONCAT(epb,_),name), code ! \ 68f4f0d8a3Sfredette .import __CONCAT(__CONCAT(epc,_),name), code ! \ 69f4f0d8a3Sfredette .import __CONCAT(__CONCAT(epd,_),name), code ! \ 70f4f0d8a3Sfredette .import __CONCAT(__CONCAT(epe,_),name), code ! \ 71f4f0d8a3Sfredette .import __CONCAT(__CONCAT(epf,_),name), code ! \ 72f4f0d8a3Sfredette .word __CONCAT(__CONCAT(ep0,_),name), __CONCAT(__CONCAT(ep1,_),name), __CONCAT(__CONCAT(ep2,_),name), __CONCAT(__CONCAT(ep3,_),name), __CONCAT(__CONCAT(ep4,_),name), __CONCAT(__CONCAT(ep5,_),name), __CONCAT(__CONCAT(ep6,_),name), __CONCAT(__CONCAT(ep7,_),name), __CONCAT(__CONCAT(ep8,_),name), __CONCAT(__CONCAT(ep9,_),name), __CONCAT(__CONCAT(epa,_),name), __CONCAT(__CONCAT(epb,_),name), __CONCAT(__CONCAT(epc,_),name), __CONCAT(__CONCAT(epd,_),name), __CONCAT(__CONCAT(epe,_),name), __CONCAT(__CONCAT(epf,_),name) 73f4f0d8a3Sfredette 74f4f0d8a3Sfredette .section .bss 75f4f0d8a3Sfredette 7693a4f7c6Sskrll .export L$fpemu_stack, data 7793a4f7c6SskrllL$fpemu_stack: 78f4f0d8a3Sfredette .comm NBPG 79f4f0d8a3Sfredette 80f4f0d8a3Sfredette .text 81f4f0d8a3Sfredette/* 82f4f0d8a3Sfredette * fpu_emulate(iir) 83f4f0d8a3Sfredette */ 84c1e4ee94SskrllLEAF_ENTRY_NOPROFILE(fpu_emulate) 85f4f0d8a3Sfredette 8606332c88Schs extru %arg0, 22, 2, %arg3 8706332c88Schs extru %arg0, 18, 3, %r31 8893a4f7c6Sskrll comib,= 1, %arg3, L$fpu_cln1 89f4f0d8a3Sfredette nop 9006332c88Schs extru %arg0, 16, 2, %r31 91f4f0d8a3Sfredette 9293a4f7c6SskrllL$fpu_cln1: 93f4f0d8a3Sfredette /* 94*8469df92Sandvar * theoretically we would need to determine the fpu instruction 95f4f0d8a3Sfredette * exception type (there could be 4 of those, but stick w/ 96f4f0d8a3Sfredette * non-timex fpus for now. 97f4f0d8a3Sfredette */ 9806332c88Schs ldi 1, %ret0 9906332c88Schs extru,<> %arg0, 10, 5, %r1 10006332c88Schs ldi 32, %r1 /* fpemu zero reg */ 10106332c88Schs extru,<> %arg0, 31, 5, %t1 10293a4f7c6Sskrll b,n L$fpemu_nzt 10393a4f7c6Sskrll comib,=,n 2, %arg3, L$fpemu_exit 10493a4f7c6SskrllL$fpemu_nzt: 10506332c88Schs copy %arg0, %t4 10606332c88Schs sh3add %r1, %arg2, %arg0 10706332c88Schs extru %arg1, 20, 2, %r1 10806332c88Schs sh3add %t1, %arg2, %arg1 109f4f0d8a3Sfredette 110f4f0d8a3Sfredette /* 111f4f0d8a3Sfredette * arg0 -- source register (address) 112f4f0d8a3Sfredette * arg1 -- target register (address) 113f4f0d8a3Sfredette * arg2 -- fpregs context 114f4f0d8a3Sfredette * arg3 -- class 115f4f0d8a3Sfredette * r31 -- subop 116f4f0d8a3Sfredette * r1 -- format specifier 117f4f0d8a3Sfredette * (t4 -- copy or arg0, ie iir) 118f4f0d8a3Sfredette */ 11993a4f7c6Sskrll comib,=,n 0, %arg3, L$fpemu0c_0 12093a4f7c6Sskrll comib,=,n 1, %arg3, L$fpemu0c_1 12193a4f7c6Sskrll comib,=,n 2, %arg3, L$fpemu0c_2 12293a4f7c6Sskrll comib,=,n 3, %arg3, L$fpemu0c_3 123f4f0d8a3Sfredette 12493a4f7c6SskrllL$fpemu0c_0: 12593a4f7c6Sskrll comib,=,n 0, %r31, L$fpemu0c_0_0 12693a4f7c6Sskrll comib,=,n 1, %r31, L$fpemu_exit 12793a4f7c6Sskrll comib,=,n 2, %r31, L$fpemu0c_0_2 12893a4f7c6Sskrll comib,=,n 3, %r31, L$fpemu0c_0_3 12993a4f7c6Sskrll comib,=,n 4, %r31, L$fpemu0c_0_4 13093a4f7c6Sskrll comib,=,n 5, %r31, L$fpemu0c_0_5 13193a4f7c6Sskrll comib,=,n 6, %r31, L$fpemu_exit 13293a4f7c6Sskrll comib,=,n 7, %r31, L$fpemu_exit 133f4f0d8a3Sfredette 13493a4f7c6SskrllL$fpemu0c_0_0: 13506332c88Schs ldi FPEMU_VERSION, %t4 13606332c88Schs stw %t4, 0(%arg2) 13706332c88Schs bv 0(%rp) 13806332c88Schs copy %r0, %ret0 139f4f0d8a3Sfredette 14093a4f7c6SskrllL$fpemu0c_0_2: /* fcpy */ 14193a4f7c6Sskrll comib,=,n 2, %r1, L$fpemu_exit 14206332c88Schs subi 3, %r1, %r1 14306332c88Schs ldw 0*4(%arg0), %t1 14406332c88Schs ldw 1*4(%arg0), %t2 14506332c88Schs ldw 2*4(%arg0), %t3 14606332c88Schs ldw 3*4(%arg0), %t4 14706332c88Schs blr,n %r1, %r0 148f4f0d8a3Sfredette nop 14906332c88Schs stw %t3, 2*4(%arg1) 15006332c88Schs stw %t4, 3*4(%arg1) 15106332c88Schs stw %t2, 1*4(%arg1) 152f4f0d8a3Sfredette nop 153f4f0d8a3Sfredette nop 154f4f0d8a3Sfredette nop 15506332c88Schs stw %t1, 0*4(%arg1) 15606332c88Schs bv 0(%rp) 15706332c88Schs copy %r0, %ret0 158f4f0d8a3Sfredette 15993a4f7c6SskrllL$fpemu0c_0_3: /* fabs */ 16093a4f7c6Sskrll comib,=,n 2, %r1, L$fpemu_exit 16106332c88Schs subi 3, %r1, %r1 16206332c88Schs ldw 0*4(%arg0), %t1 16306332c88Schs ldw 1*4(%arg0), %t2 16406332c88Schs ldw 2*4(%arg0), %t3 16506332c88Schs ldw 3*4(%arg0), %t4 16606332c88Schs depi 0, 0, 1, %t1 16706332c88Schs blr,n %r1, %r0 168f4f0d8a3Sfredette nop 16906332c88Schs stw %t3, 2*4(%arg1) 17006332c88Schs stw %t4, 3*4(%arg1) 17106332c88Schs stw %t2, 1*4(%arg1) 172f4f0d8a3Sfredette nop 173f4f0d8a3Sfredette nop 174f4f0d8a3Sfredette nop 17506332c88Schs stw %t1, 0*4(%arg1) 17606332c88Schs bv 0(%rp) 17706332c88Schs copy %r0, %ret0 178f4f0d8a3Sfredette 17993a4f7c6SskrllL$fpemu0c_0_4: /* fsqrt */ 180f4f0d8a3Sfredette /* quad not implemented */ 181f4f0d8a3Sfredette FP_TABLE2(fsqrt,sgl,dbl,invalid,invalid) 182f4f0d8a3Sfredette 18393a4f7c6SskrllL$fpemu0c_0_5: /* frnd */ 184f4f0d8a3Sfredette /* quad not implemented */ 185f4f0d8a3Sfredette FP_TABLE2(frnd,sgl,dbl,invalid,quad) 186f4f0d8a3Sfredette 18793a4f7c6SskrllL$fpemu0c_1: 18806332c88Schs extru %t4, 18, 2, %t2 18906332c88Schs sh2add %r1, %t2, %r1 19093a4f7c6Sskrll comib,=,n 0, %r31, L$fpemu0c_1_0 19193a4f7c6Sskrll comib,=,n 1, %r31, L$fpemu0c_1_1 19293a4f7c6Sskrll comib,=,n 2, %r31, L$fpemu0c_1_2 19393a4f7c6Sskrll comib,=,n 3, %r31, L$fpemu0c_1_3 194f4f0d8a3Sfredette 19593a4f7c6SskrllL$fpemu0c_1_0: /* fcnvff */ 196f4f0d8a3Sfredette#define sgl_to_quad_fcnvff invalid_fcnvff 197f4f0d8a3Sfredette#define dbl_to_quad_fcnvff invalid_fcnvff 198f4f0d8a3Sfredette#define quad_to_sgl_fcnvff invalid_fcnvff 199f4f0d8a3Sfredette#define quad_to_dbl_fcnvff invalid_fcnvff 200f4f0d8a3Sfredette FP_TABLE3(fcnvff, invalid, sgl_to_dbl, invalid, sgl_to_quad, dbl_to_sgl, invalid, invalid, dbl_to_quad, invalid, invalid, invalid, invalid, quad_to_sgl, quad_to_dbl, invalid, invalid) 201f4f0d8a3Sfredette 20293a4f7c6SskrllL$fpemu0c_1_1: /* fcnvxf */ 203f4f0d8a3Sfredette#define sgl_to_quad_fcnvxf invalid_fcnvxf 204f4f0d8a3Sfredette#define dbl_to_quad_fcnvxf invalid_fcnvxf 205f4f0d8a3Sfredette#define quad_to_sgl_fcnvxf invalid_fcnvxf 206f4f0d8a3Sfredette#define quad_to_dbl_fcnvxf invalid_fcnvxf 207f4f0d8a3Sfredette#define quad_to_quad_fcnvxf invalid_fcnvxf 208f4f0d8a3Sfredette FP_TABLE3(fcnvxf, sgl_to_sgl, sgl_to_dbl, invalid, sgl_to_quad, dbl_to_sgl, dbl_to_dbl, invalid, dbl_to_quad, invalid, invalid, invalid, invalid, quad_to_sgl, quad_to_dbl, invalid, quad_to_quad) 209f4f0d8a3Sfredette 21093a4f7c6SskrllL$fpemu0c_1_2: /* fcnvfx */ 211f4f0d8a3Sfredette#define sgl_to_quad_fcnvfx invalid_fcnvfx 212f4f0d8a3Sfredette#define dbl_to_quad_fcnvfx invalid_fcnvfx 213f4f0d8a3Sfredette#define quad_to_sgl_fcnvfx invalid_fcnvfx 214f4f0d8a3Sfredette#define quad_to_dbl_fcnvfx invalid_fcnvfx 215f4f0d8a3Sfredette#define quad_to_quad_fcnvfx invalid_fcnvfx 216f4f0d8a3Sfredette FP_TABLE3(fcnvfx, sgl_to_sgl, sgl_to_dbl, invalid, sgl_to_quad, dbl_to_sgl, dbl_to_dbl, invalid, dbl_to_quad, invalid, invalid, invalid, invalid, quad_to_sgl, quad_to_dbl, invalid, quad_to_quad) 217f4f0d8a3Sfredette 21893a4f7c6SskrllL$fpemu0c_1_3: /* fcnvfxt */ 219f4f0d8a3Sfredette#define sgl_to_quad_fcnvfxt invalid_fcnvfxt 220f4f0d8a3Sfredette#define dbl_to_quad_fcnvfxt invalid_fcnvfxt 221f4f0d8a3Sfredette#define quad_to_sgl_fcnvfxt invalid_fcnvfxt 222f4f0d8a3Sfredette#define quad_to_dbl_fcnvfxt invalid_fcnvfxt 223f4f0d8a3Sfredette#define quad_to_quad_fcnvfxt invalid_fcnvfxt 224f4f0d8a3Sfredette FP_TABLE3(fcnvfxt, sgl_to_sgl, sgl_to_dbl, invalid, sgl_to_quad, dbl_to_sgl, dbl_to_dbl, invalid, dbl_to_quad, invalid, invalid, invalid, invalid, quad_to_sgl, quad_to_dbl, invalid, quad_to_quad) 225f4f0d8a3Sfredette 226f4f0d8a3Sfredette 22793a4f7c6SskrllL$fpemu0c_2: 22893a4f7c6Sskrll comib,=,n 0, %r31, L$fpemu0c_2_0 22993a4f7c6Sskrll comib,=,n 1, %r31, L$fpemu0c_2_1 23093a4f7c6Sskrll comib,=,n 2, %r31, L$fpemu_exit 23193a4f7c6Sskrll comib,=,n 3, %r31, L$fpemu_exit 23293a4f7c6Sskrll comib,=,n 4, %r31, L$fpemu_exit 23393a4f7c6Sskrll comib,=,n 5, %r31, L$fpemu_exit 23493a4f7c6Sskrll comib,=,n 6, %r31, L$fpemu_exit 23593a4f7c6Sskrll comib,=,n 7, %r31, L$fpemu_exit 236f4f0d8a3Sfredette 23793a4f7c6SskrllL$fpemu0c_2_0: 23806332c88Schs copy %arg2, %arg3 23906332c88Schs extru,<> %t4, 15, 5, %t1 24006332c88Schs ldi 32, %t1 24106332c88Schs sh3add %t1, %arg3, %arg1 24206332c88Schs extru %t4, 31, 5, %arg2 243f4f0d8a3Sfredette FP_TABLE2(fcmp,sgl,dbl,invalid,invalid) 244f4f0d8a3Sfredette 24593a4f7c6SskrllL$fpemu0c_2_1: 24693a4f7c6Sskrll comib,<>,n 0, %r1, L$fpemu_exit 247f4f0d8a3Sfredette 24806332c88Schs /* extru %t4, 31, 5, %arg1 */ 249f4f0d8a3Sfredette /* XXX timex is much more compilicated */ 25006332c88Schs ldw 0(%arg2), %t1 25106332c88Schs ldi 0, %ret0 25206332c88Schs extru,<> %t1, 5, 1, %r0 25306332c88Schs bv,n %r0(%rp) 254f4f0d8a3Sfredette 255f4f0d8a3Sfredette /* advance the pcqueue */ 25606332c88Schs mtctl %r0, %pcsq 25706332c88Schs mfctl %pcsq, %t2 25806332c88Schs mtctl %t2, %pcsq 25906332c88Schs mtctl %t2, %pcsq 26006332c88Schs mtctl %r0, %pcoq 26106332c88Schs mfctl %pcoq, %t2 26206332c88Schs mtctl %t2, %pcoq 26306332c88Schs ldo 4(%t2), %t2 26406332c88Schs bv %r0(%rp) 26506332c88Schs mtctl %t2, %pcoq 266f4f0d8a3Sfredette 26793a4f7c6SskrllL$fpemu0c_3: 26806332c88Schs copy %arg2, %arg3 26906332c88Schs extru,<> %t4, 31, 5, %t1 27006332c88Schs ldi 32, %t1 27106332c88Schs sh3add %t1, %arg3, %arg2 272f4f0d8a3Sfredette 27393a4f7c6Sskrll comib,=,n 0, %r31, L$fpemu0c_3_0 27493a4f7c6Sskrll comib,=,n 1, %r31, L$fpemu0c_3_1 27593a4f7c6Sskrll comib,=,n 2, %r31, L$fpemu0c_3_2 27693a4f7c6Sskrll comib,=,n 3, %r31, L$fpemu0c_3_3 27793a4f7c6Sskrll comib,=,n 4, %r31, L$fpemu0c_3_4 27893a4f7c6Sskrll comib,=,n 5, %r31, L$fpemu_exit 27993a4f7c6Sskrll comib,=,n 6, %r31, L$fpemu_exit 28093a4f7c6Sskrll comib,=,n 7, %r31, L$fpemu_exit 281f4f0d8a3Sfredette 28293a4f7c6SskrllL$fpemu0c_3_0: /* fadd */ 283f4f0d8a3Sfredette FP_TABLE2(fadd,sgl,dbl,invalid,invalid) 284f4f0d8a3Sfredette 28593a4f7c6SskrllL$fpemu0c_3_1: /* fsub */ 286f4f0d8a3Sfredette FP_TABLE2(fsub,sgl,dbl,invalid,invalid) 287f4f0d8a3Sfredette 28893a4f7c6SskrllL$fpemu0c_3_2: /* fmpy */ 289f4f0d8a3Sfredette FP_TABLE2(fmpy,sgl,dbl,invalid,invalid) 290f4f0d8a3Sfredette 29193a4f7c6SskrllL$fpemu0c_3_3: /* fdiv */ 292f4f0d8a3Sfredette FP_TABLE2(fdiv,sgl,dbl,invalid,invalid) 293f4f0d8a3Sfredette 29493a4f7c6SskrllL$fpemu0c_3_4: /* frem */ 295f4f0d8a3Sfredette FP_TABLE2(frem,sgl,dbl,invalid,invalid) 296f4f0d8a3Sfredette 29793a4f7c6Sskrll .export L$fpemu_exit, code 29893a4f7c6SskrllL$fpemu_exit: 299f4f0d8a3Sfredette /* these look very ugly, but we don't want to mess up w/ m4 just 300f4f0d8a3Sfredette * for the sake of overall world prettieness value growth XXX */ 30106332c88Schsinvalid_fsqrt: 30206332c88Schsinvalid_frnd: 30306332c88Schsinvalid_fcnvff: 30406332c88Schsinvalid_fcnvxf: 30506332c88Schsinvalid_fcnvfx: 30606332c88Schsinvalid_fcnvfxt: 30706332c88Schsinvalid_fcmp: 30806332c88Schsinvalid_fadd: 30906332c88Schsinvalid_fsub: 31006332c88Schsinvalid_fmpy: 31106332c88Schsinvalid_fdiv: 31206332c88Schsinvalid_frem: 31306332c88Schs bv,n 0(%rp) 314f4f0d8a3SfredetteEXIT(fpu_emulate) 315f4f0d8a3Sfredette 316f4f0d8a3Sfredette 317f4f0d8a3Sfredette .end 318f4f0d8a3Sfredette 319