📄 emulate.s
字号:
/* * Copyright (c) 1986, 1987 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * Mt. Xinu. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)emulate.s 7.5 (Berkeley) 6/28/90 */#if VAX630 || VAX650/* * String instruction emulation - MicroVAX only. These routines are called * from locore.s when an "emulate" fault occurs on the MicroVAX. They are * called with the stack set up as follows: * * (sp): Return address of trap handler * 4(sp): Instruction Opcode (also holds PSL result from emulator) * 8(sp): Instruction PC * 12(sp): Operand 1 * 16(sp): Operand 2 * 20(sp): Operand 3 * 24(sp): Operand 4 * 28(sp): Operand 5 * 32(sp): Operand 6 * 36(sp): old Register 11 * 40(sp): old Register 10 * 44(sp): Return PC * 48(sp): Return PSL * 52(sp): TOS before instruction * * R11 and r10 are available for use. If any routine needs to use r9-r1 * they need to save them first (unless those registers are SUPPOSED to be * messed with by the "instruction"). These routines leave their results * in registers 0-5 explicitly, as needed, and use the macros defined below * to link up with calling routine. */#define return rsb#define savepsl movpsl 4(sp)#define setpsl(reg) movl reg,4(sp)#define overflowpsl movl $2,4(sp)#define arg1 12(sp)#define arg2 16(sp)#define arg3 20(sp)#define arg4 24(sp)#define arg5 28(sp)#define arg6 32(sp)#define argub(num,reg) movzbl 8+4*num(sp),reg#define arguw(num,reg) movzwl 8+4*num(sp),reg#define argul(num,reg) movl 8+4*num(sp),reg#define argb(num,reg) cvtbl 8+4*num(sp),reg#define argw(num,reg) cvtwl 8+4*num(sp),reg#define argl(num,reg) movl 8+4*num(sp),reg#define toarg(reg,num) movl reg,8+4*num(sp) .text .align 1 .globl _EMcrc_EMcrc: argl(1,r11) # (1) table address == r11 argl(2,r0) # (2) initial crc == r0 argl(4,r3) # (4) source address == r3 arguw(3,r2) # (3) source length == r2 jeql Lcrc_outLcrc_loop: xorb2 (r3)+,r0 extzv $0,$4,r0,r10 extzv $4,$28,r0,r1 xorl3 r1,(r11)[r10],r0 extzv $0,$4,r0,r10 extzv $4,$28,r0,r1 xorl3 r1,(r11)[r10],r0 sobgtr r2,Lcrc_loop tstl r0Lcrc_out: savepsl clrl r1 return .align 1 .globl _EMmovtc_EMmovtc: arguw(1,r0) # (1) source length == r0 argl(2,r1) # (2) source address == r1 argub(3,r11) # (3) fill character == r11 argl(4,r3) # (4) table address == r3 argl(6,r5) # (6) destination address == r5 arguw(5,r4) # (5) destination length == r4 jeql Lmovtc_outLmovtc_loop: tstl r0 jeql Lmovtc_2loop movzbl (r1)+,r2 movb (r3)[r2],(r5)+ decl r0 sobgtr r4,Lmovtc_loop jbr Lmovtc_outLmovtc_2loop: movb r11,(r5)+ sobgtr r4,Lmovtc_2loopLmovtc_out: cmpl r4,r0 savepsl clrl r2 return .align 1 .globl _EMmovtuc_EMmovtuc: arguw(1,r0) # (1) source length == r0 argl(2,r1) # (2) source address == r1 argub(3,r11) # (3) escape character == r11 argl(4,r3) # (4) table address == r3 argl(6,r5) # (6) destination address == r5 arguw(5,r4) # (5) destination length == r4 jeql Lmovtuc_outLmovtuc_loop: tstl r0 jeql Lmovtuc_out movzbl (r1),r2 movzbl (r3)[r2],r2 cmpl r2,r11 jeql Lmovtuc_out movzbl (r1)+,r2 movb (r3)[r2],(r5)+ decl r0 sobgtr r4,Lmovtuc_loopLmovtuc_out: cmpl r4,r0 savepsl clrl r2 return .align 1 .globl _EMmatchc_EMmatchc: argl(2,r10) # (2) substring address == r10 arguw(3,r2) # (3) source length == r2 argl(4,r3) # (4) source address == r3 arguw(1,r11) # (1) substring length == r11 jeql Lmatchc_out # temp source address == r1 addl2 r10,r11 # temp substring address == r0 tstl r2 jeql Lmatchc_outLmatchc_loop: cmpb (r10),(r3) jneq Lmatchc_fail movl r3,r1 movl r10,r0Lmatchc_2loop: cmpl r0,r11 jeql Lmatchc_succ cmpb (r0)+,(r1)+ jeql Lmatchc_2loopLmatchc_fail: incl r3 sobgtr r2,Lmatchc_loop movl r10,r1 subl3 r10,r11,r0 jbr Lmatchc_outLmatchc_succ: movl r1,r3 movl r11,r1 clrl r0Lmatchc_out: savepsl return .align 1 .globl _EMspanc_EMspanc: argl(2,r1) # (2) string address == r1 argub(4,r2) # (4) character-mask == r2 argl(3,r3) # (3) table address == r3 arguw(1,r0) # (1) string length == r0 jeql Lspanc_outLspanc_loop: movzbl (r1),r11 mcomb (r3)[r11],r11 bicb3 r11,r2,r11 jeql Lspanc_out incl r1 sobgtr r0,Lspanc_loopLspanc_out: savepsl clrl r2 return .align 1 .globl _EMscanc_EMscanc: argl(2,r1) # (2) string address == r1 argub(4,r2) # (4) character-mask == r2 argl(3,r3) # (3) table address == r3 arguw(1,r0) # (1) string length == r0 jeql Lscanc_outLscanc_loop: movzbl (r1),r11 mcomb (r3)[r11],r11 bicb3 r11,r2,r11 jneq Lscanc_out incl r1 sobgtr r0,Lscanc_loopLscanc_out: savepsl clrl r2 return .align 1 .globl _EMskpc_EMskpc: argub(1,r11) # (1) character == r11 argl(3,r1) # (3) string address == r1 arguw(2,r0) # (2) string length == r0 jeql Lskpc_out # forget zero length stringsLskpc_loop: cmpb (r1),r11 jneq Lskpc_out incl r1 sobgtr r0,Lskpc_loopLskpc_out: tstl r0 # be sure of condition codes savepsl return .align 1 .globl _EMlocc_EMlocc: argub(1,r11) # (1) character == r11 argl(3,r1) # (3) string address == r1 arguw(2,r0) # (2) string length == r0 jeql Lskpc_out # forget zero length stringsLlocc_loop: cmpb (r1),r11 jeql Llocc_out incl r1 sobgtr r0,Llocc_loopLlocc_out: tstl r0 # be sure of condition codes savepsl return .align 1 .globl _EMcmpc3_EMcmpc3: argl(2,r1) # (2) string1 address == r1 argl(3,r3) # (3) string2 address == r3 arguw(1,r0) # (1) strings' length == r0 jeql Lcmpc3_outLcmpc3_loop: cmpb (r1),(r3) jneq Lcmpc3_out incl r1 incl r3 sobgtr r0,Lcmpc3_loopLcmpc3_out: savepsl movl r0,r2 return .align 1 .globl _EMcmpc5_EMcmpc5: argl(2,r1) # (2) string1 address == r1 argub(3,r11) # (1) fill character == r11 arguw(4,r2) # (1) string2 length == r2 argl(5,r3) # (3) string2 address == r3 arguw(1,r0) # (1) string1 length == r0 jeql Lcmpc5_str2Lcmpc5_loop: tstl r2 jeql Lcmpc5_str1loop cmpb (r1),(r3) jneq Lcmpc5_out incl r1 incl r3 decl r2 sobgtr r0,Lcmpc5_loopLcmpc5_str2: tstl r2 jeql Lcmpc5_outLcmpc5_str2loop: cmpb r11,(r3) jneq Lcmpc5_out incl r3 sobgtr r2,Lcmpc5_str2loop jbr Lcmpc5_outLcmpc5_str1loop: cmpb (r1),r11 jneq Lcmpc5_out incl r1 sobgtr r0,Lcmpc5_str1loopLcmpc5_out: savepsl return/* * Packed Decimal string operations */#define POSITIVE $12#define NEGATIVE $13#define NEGATIVEalt $11 .align 1 .globl _EMaddp4_EMaddp4: toarg(r9,6) # save register r9 in arg6 spot arguw(1,r11) # (1) source length == r11 argl(2,r10) # (2) source address == r10 arguw(3,r9) # (3) destination length == r9 argl(4,r3) # (4) destination address == r3 # arg4 will be needed later # arg5 holds destination address of LSNibble temporarily ashl $-1,r11,r11 addl2 r11,r10 # source address of LSNibble incl r11 # source length is in bytes ashl $-1,r9,r9 addl2 r9,r3 # r3 = destination address of LSNibble incl r9 # destination length is in bytes toarg(r3,5) # stored in arg5 spot extzv $0,$4,(r3),r2 # set standard +/- indicators in destination cmpl r2,NEGATIVE jeql L112 cmpl r2,NEGATIVEalt jeql L111 insv POSITIVE,$0,$4,(r3) jbr L112L111: insv NEGATIVE,$0,$4,(r3)L112: extzv $0,$4,(r10),r2 # r2 = standard +/- of source cmpl r2,NEGATIVE jeql L114 cmpl r2,NEGATIVEalt jeql L113 movl POSITIVE,r2 jbr L114L113: movl NEGATIVE,r2L114: cmpl r11,r9 # if source is longer than destination jleq L115 movl r9,r11 # set source length == destination lengthL115: extzv $4,$4,(r3),r9 # r9 = LSDigit of destination extzv $4,$4,(r10),r1 # r1 = LSDigit of source extzv $0,$4,(r3),r0 cmpl r0,r2 # if signs of operands are not equal jeql Laddp4_same # do a subtraction clrl r2 # r2 is non-zero if result is non-zero subl2 r1,r9 # r9 = "addition" of operands' high nibble jbr L119 # jump into addition loopLaddp4_diff_loop: decl r3 extzv $0,$4,(r3),r0 addl2 r0,r1 # r1 = carry + next (low) nibble of source decl r10 extzv $0,$4,(r10),r0 subl2 r0,r1 # r1 -= next (low) nibble of destination jgeq L121 # if negative result mnegl $1,r9 # r9 == carry = -1 addl2 $10,r1 # r1 == result += 10 jbr L122 # elseL121: clrl r9 # r9 == carry = 0L122: insv r1,$0,$4,(r3) # store result low nibble bisl2 r1,r2 extzv $4,$4,(r3),r0 addl2 r0,r9 # r9 = carry + next (high) nibble of source extzv $4,$4,(r10),r0 subl2 r0,r9 # r9 -= next (high) nibble of destinationL119: jgeq L117 # if negative result mnegl $1,r1 # r1 == carry = -1 addl2 $10,r9 # r9 == result += 10 jbr L118 # elseL117: clrl r1 # r1 == carry = 0L118: insv r9,$4,$4,(r3) # store result high nibble bisl2 r9,r2 # r2 is non-zero if result is non-zero decl r11 # while (--source length) jneq Laddp4_diff_loop argl(4,r10) # r10 = address of destination MSNibble jbr Laddp4_diff_carryLaddp4_diff_carlop: decl r3 extzv $0,$4,(r3),r0 addl2 r0,r1 # r1 == carry += next (low) nibble jgeq L127 # if less than zero
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -